Page
Library
Module
Module type
Parameter
Class
Class type
Source
Cumulus
SourceDifferential Signals
('a, 'da) change
represents the value and latest change of a cumulus signal. Normally a signal goes from Init
to a series of Patch
possibly. The series of Patch
es may be interspersed with Keep
for functions which observe the signal between its changes.
Init
may also occur later in the series for some cumulus signals and indicates that it has been reinitialized. Such a cumulus signals are said to be discontinuous.
A shortcut for the function type used to represent updates to a cumulus signal. The function takes the current value of the signal and the result indicates the next value and how it changed from the current value. Patch (x', dx)
announces that the value changed to x'
with dx
holding information about the difference from the current value x
to x'
. Keep x
announces that the cumulus signal will remain unchanged, where x
must be the argument to the update function. Init x'
can be used to reinitialize the cumulus signal, introducing a discontinuity.
create v
is a (v, f)
where v
is a new cumulus signal starting with the value v
and which can be updated by calling f
.
of_event e
is the cumulus signal having no state and reporting events from e
as its changes.
of_signal s
is a cumulus signal holding the same value as s
at any time while providing no differential information about the changes.
hold v e
is the cumulus signal starting at v
, then taking values from e
while providing no differential information about the changes.
integrate f e v
is the cumulus signal starting off with v
then for each occurrence dx
of e
, then signal is updated by f dx
with dx
reported as the change.
stop c
changes c
into a constant cumulus signal holding the latest value. The strong
parameter is relevant for platforms which don't have weak references. See the React library for details.
value c
is the currently held value of c
. This should not be called during an update step.
signal c
is the react signal holding the same value as c
at any time.
These functions cover the common case of deriving new cumulus signals from existing ones. This is done by providing a function ~init
which constructs the initial value from the latest values of the source signals, and a function ~patch
which provides an update given the latest values and changes of the source signals. The following example combines two cumulus signals by pairing the values and combining the differentials:
let c =
let init x1 x2 = (x1, x2) in
let patch (x1, dx1) (x2, dx2) y =
(match dx1, dx2 with
| None, None -> Cumulus.Keep y
| Some dx1, None -> Cumulus.Patch ((x1, x2), `Left dx1)
| None, Some dx2 -> Cumulus.Patch ((x1, x2), `Right dx2)
| Some dx1, Some dx2 -> Cumulus.Patch ((x1, x2), `Both (dx1, dx2)))
in
Cumulus.l2 ~init ~patch c1 c2
The main difference from full lifting is that a discontinuity of any of the source signals will cause a discontinuity in the constructed signal, meaning that ~init
will be called instead of ~patch
, which for the common case of continuous cumulus signals makes no difference.
val l6 :
init:('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g) ->
patch:
(('a * 'da option) ->
('b * 'db option) ->
('c * 'dc option) ->
('d * 'dd option) ->
('e * 'de option) ->
('f * 'df option) ->
('g, 'dg) update) ->
('a, 'da) t ->
('b, 'db) t ->
('c, 'dc) t ->
('d, 'dd) t ->
('e, 'de) t ->
('f, 'df) t ->
('g, 'dg) t