module S:Signal combinators.sig
..end
Consult their semantics.
type'a
t ='a React.signal
'a
.val const : 'a -> 'a React.signal
const v
is always v
, [const v
]t = v
.val create : ?eq:('a -> 'a -> bool) -> 'a -> 'a React.signal * ('a -> unit)
create i
is a primitive signal s
set to i
and a
set
function. set v
sets the signal's value to v
at the
time it is called and triggers an update
cycle.
Warning. send
must not be executed inside an update cycle.
val value : 'a React.signal -> 'a
value s
is s
's current value.
Warning. If executed in an update
cycle may return a non up-to-date value or raise Failure
if
the signal is not yet initialized.
val retain : 'a React.signal -> (unit -> unit) -> [ `R of unit -> unit ]
retain s c
keeps a reference to the closure c
in s
and
returns the previously retained value. c
will never be
invoked.
Raises. Invalid_argument
on constant signals.
val stop : 'a React.signal -> unit
stop s
, stops updating s
. It conceptually becomes React.S.const
with the signal's last value and cannot be restarted. Allows to
disable effectful signals.
Note. If executed in an update cycle the signal may
still update in the cycle.
val equal : ?eq:('a -> 'a -> bool) -> 'a React.signal -> 'a React.signal -> bool
equal s s'
is true
iff s
and s'
are equal. If both
signals are React.S.const
ant eq
is used between their value
(defauts to structural equality). If both signals are not
React.S.const
ant, physical equality is used.val trace : ?iff:bool t -> ('a -> unit) -> 'a React.signal -> 'a React.signal
trace iff tr s
is s
except tr
is invoked with s
's
current value and on s
changes when iff
is true
(defaults
to S.const true
). For all t where [s
]t = v
and (t = 0
or ([s
]t-dt= v'
and eq v v' = false
)) and
[iff
]t = true
, tr
is invoked with v
.val hold : ?eq:('a -> 'a -> bool) -> 'a -> 'a React.event -> 'a React.signal
hold i e
has the value of e
's last occurrence or i
if there
wasn't any.
hold i e
]t = i
if [e
]<=t = None
hold i e
]t = v
if [e
]<=t = Some v
val app : ?eq:('b -> 'b -> bool) ->
('a -> 'b) React.signal -> 'a React.signal -> 'b React.signal
app sf s
holds the value of sf
applied
to the value of s
, [app sf s
]t
=
[sf
]t [s
]t.val map : ?eq:('b -> 'b -> bool) -> ('a -> 'b) -> 'a React.signal -> 'b React.signal
map f s
is s
transformed by f
, [map f s
]t = f
[s
]t.val filter : ?eq:('a -> 'a -> bool) ->
('a -> bool) -> 'a -> 'a React.signal -> 'a React.signal
filter f i s
is s
's values that satisfy p
. If a value does not
satisfy p
it holds the last value that was satisfied or i
if
there is none.
filter p s
]t =
[s
]t if p
[s
]t = true
.filter p s
]t =
[s
]t' if p
[s
]t = false
and t' is the greatest t' < t with p
[s
]t' = true
.filter p e
]t = i
otherwise.val fmap : ?eq:('b -> 'b -> bool) ->
('a -> 'b option) -> 'b -> 'a React.signal -> 'b React.signal
fmap fm i s
is s
filtered and mapped by fm
.
fmap fm i s
]t =
v if fm
[s
]t = Some v
.fmap fm i s
]t =
[fmap fm i s
]t' if fm
[s
]t = None
and t' is the greatest t' < t with fm
[s
]t' <> None
.fmap fm i s
]t = i
otherwise.val diff : ('a -> 'a -> 'b) -> 'a React.signal -> 'b React.event
diff f s
is an event with occurrences whenever s
changes from
v'
to v
and eq v v'
is false
(eq
is the signal's equality
function). The value of the occurrence is f v v'
.
diff f s
]t = Some d
if [s
]t = v
and [s
]t-dt = v'
and eq v v' = false
and f v v' = d
.diff f s
]t = None
otherwise.val changes : 'a React.signal -> 'a React.event
changes s
is diff (fun v _ -> v) s
.val sample : ('b -> 'a -> 'c) -> 'b React.event -> 'a React.signal -> 'c React.event
sample f e s
samples s
at e
's occurrences.
sample f e s
]t = Some (f ev sv)
if [e
]t = Some ev
and [s
]t = sv
.sample e s
]t = None
otherwise.val when_ : ?eq:('a -> 'a -> bool) ->
bool React.signal -> 'a -> 'a React.signal -> 'a React.signal
when_ c i s
is the signal s
whenever c
is true
.
When c
is false
it holds the last value s
had when
c
was the last time true
or i
if it never was.
when_ c i s
]t =
[s
]t if [c
]t = true
when_ c i s
]t =
[s
]t' if [c
]t = false
where t' is the greatest t' < t with [c
]t' = true
.when_ c i s
]t =
i
otherwise.val dismiss : ?eq:('a -> 'a -> bool) ->
'b React.event -> 'a -> 'a React.signal -> 'a React.signal
dismiss c i s
is the signal s
except changes when c
occurs
are ignored. If c
occurs initially i
is used.
dismiss c i s
]t =
[s
]t'
where t' is the greatest t' <= t with [c
]t' = None
and
[s
]t'-dt <>
[s
]t'dismiss_ c i s
]0 =
v
where v = i
if
[c
]0 = Some _
and v =
[s
]0 otherwise.val accum : ?eq:('a -> 'a -> bool) -> ('a -> 'a) React.event -> 'a -> 'a React.signal
val fold : ?eq:('a -> 'a -> bool) ->
('a -> 'b -> 'a) -> 'a -> 'b React.event -> 'a React.signal
val merge : ?eq:('a -> 'a -> bool) ->
('a -> 'b -> 'a) -> 'a -> 'b React.signal list -> 'a React.signal
merge f a sl
merges the value of every signal in sl
using f
and the accumulator a
.
[merge f a sl
]t
= List.fold_left f a (List.map
[]t sl)
.
val switch : ?eq:('a -> 'a -> bool) ->
'a React.signal -> 'a React.signal React.event -> 'a React.signal
switch s es
is s
until there is an
occurrence s'
on es
, s'
is then used
until there is a new occurrence on es
, etc..
switch s es
]t =
[s
]t if [es
]<=t = None
.switch s es
]t =
[s'
]t if [es
]<=t
= Some s'
.val fix : ?eq:('a -> 'a -> bool) ->
'a -> ('a React.signal -> 'a React.signal * 'b) -> 'b
fix i sf
allow to refer to the value a signal had an
infinitesimal amount of time before.
In fix sf
, sf
is called with a signal s
that represents
the signal returned by sf
delayed by an infinitesimal amount
time. If s', r = sf s
then r
is returned by fix
and s
is such that :
s
]t =
i
for t = 0. s
]t =
[s'
]t-dt otherwise.
eq
is the equality used by s
.
Raises. Invalid_argument
if s'
is directly a delayed signal (i.e.
a signal given to a fixing function).
Note. Regarding values depending on the result r
of
s', r = sf s
the following two cases need to be distinguished :
sf s
is applied, s'
does not depend on
a value that is in a cycle and s
has no dependents in a cycle (e.g
in the simple case where fix
is applied outside a cycle).
In that case if the initial value of s'
differs from i
,
s
and its dependents need to be updated and a special
update cycle will be triggered for this. Values
depending on the result r
will be created only after this
special update cycle has finished (e.g. they won't see
the i
of s
if r = s
).
r
will be created in the same
cycle as s
and s'
(e.g. they will see the i
of s
if r = s
).
Lifting combinators. For a given n
the semantics is :
[ln f a1
... an
]t = f [a1
]t ... [an
]t
val l1 : ?eq:('b -> 'b -> bool) -> ('a -> 'b) -> 'a React.signal -> 'b React.signal
val l2 : ?eq:('c -> 'c -> bool) ->
('a -> 'b -> 'c) -> 'a React.signal -> 'b React.signal -> 'c React.signal
val l3 : ?eq:('d -> 'd -> bool) ->
('a -> 'b -> 'c -> 'd) ->
'a React.signal -> 'b React.signal -> 'c React.signal -> 'd React.signal
val l4 : ?eq:('e -> 'e -> bool) ->
('a -> 'b -> 'c -> 'd -> 'e) ->
'a React.signal ->
'b React.signal -> 'c React.signal -> 'd React.signal -> 'e React.signal
val l5 : ?eq:('f -> 'f -> bool) ->
('a -> 'b -> 'c -> 'd -> 'e -> 'f) ->
'a React.signal ->
'b React.signal ->
'c React.signal -> 'd React.signal -> 'e React.signal -> 'f React.signal
val l6 : ?eq:('g -> 'g -> bool) ->
('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g) ->
'a React.signal ->
'b React.signal ->
'c React.signal ->
'd React.signal -> 'e React.signal -> 'f React.signal -> 'g React.signal
Pervasives
functions and
operators.module Bool:sig
..end
module Int:sig
..end
module Float:sig
..end
module Pair:sig
..end
module Compare:sig
..end
Given an equality function equal
and a type t
, the functor
React.S.Make
automatically applies the eq
parameter of the combinators.
The outcome is combinators whose results are signals with
values in t
.
Basic types are already specialized in the module React.S.Special
, open
this module to use them.
module type EqType =sig
..end
React.S.Make
module type S =sig
..end
React.S.Make
module Make:
module Special:sig
..end