# Module `React.S`

Signal combinators.

Consult their semantics.

## Primitive and basics

`type 'a t`

`= 'a signal`

The type for signals of type

`'a`

.

`val const : 'a -> 'a signal`

`const v`

is always`v`

, [`const v`

]_{t}`= v`

.

`val create : ?eq:('a -> 'a -> bool) -> 'a -> 'a signal * (?step:step -> 'a -> unit)`

`create i`

is a primitive signal`s`

set to`i`

and a`set`

function. The function`set`

is such that:`set v`

sets the signal's value to`v`

at the time it is called and triggers an update step.`set ~step v`

sets the signal's value to`v`

at the time it is called and updates it dependencies when`step`

is executed`set ~step v`

raises`Invalid_argument`

if it was previously called with a step and this step has not executed yet or if the given`step`

was already executed.

**Warning.**`set`

must not be executed inside an update step.

`val value : 'a signal -> 'a`

`value s`

is`s`

's current value.**Warning.**If executed in an update step may return a non up-to-date value or raise`Failure`

if the signal is not yet initialized.

`val retain : 'a 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 : ?strong:bool -> 'a signal -> unit`

`stop s`

, stops updating`s`

. It conceptually becomes`const`

with the signal's last value and cannot be restarted. Allows to disable effectful signals.The

`strong`

argument should only be used on platforms where weak arrays have a strong semantics (i.e. JavaScript). See details.**Note.**If executed in an update step the signal may still update in the step.

`val equal : ?eq:('a -> 'a -> bool) -> 'a signal -> 'a signal -> bool`

`equal s s'`

is`true`

iff`s`

and`s'`

are equal. If both signals are`const`

ant`eq`

is used between their value (defauts to structural equality). If both signals are not`const`

ant, physical equality is used.

`val trace : ?iff:bool t -> ('a -> unit) -> 'a signal -> 'a 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`

.

## From events

## Transforming and filtering

`val app : ?eq:('b -> 'b -> bool) -> ('a -> 'b) signal -> 'a signal -> 'b 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 signal -> 'b 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 signal -> 'a 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 signal -> 'b 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 signal -> 'b 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 sample : ('b -> 'a -> 'c) -> 'b event -> 'a signal -> 'c 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 on : ?eq:('a -> 'a -> bool) -> bool signal -> 'a -> 'a signal -> 'a signal`

`on 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.- [
`on c i s`

]_{t}`=`

[`s`

]_{t}if [`c`

]_{t}`= true`

- [
`on c i s`

]_{t}`=`

[`s`

]_{t'}if [`c`

]_{t}`= false`

where t' is the greatest t' < t with [`c`

]_{t'}`= true`

. - [
`on c i s`

]_{t}`=`

`i`

otherwise.

- [

`val dismiss : ?eq:('a -> 'a -> bool) -> 'b event -> 'a -> 'a signal -> 'a 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.

- [

## Accumulating

`val accum : ?eq:('a -> 'a -> bool) -> ('a -> 'a) event -> 'a -> 'a signal`

`accum e i`

is`S.hold i (`

Accumulating`e i)`

.

## Combining

`val merge : ?eq:('a -> 'a -> bool) -> ('a -> 'b -> 'a) -> 'a -> 'b signal list -> 'a 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 signal signal -> 'a signal`

`switch ss`

is the inner signal of`ss`

.- [
`switch ss`

]_{t}`=`

[[`ss`

]_{t}]_{t}.

- [

`val bind : ?eq:('b -> 'b -> bool) -> 'a signal -> ('a -> 'b signal) -> 'b signal`

`bind s sf`

is`switch (map ~eq:( == ) sf s)`

.

`val fix : ?eq:('a -> 'a -> bool) -> 'a -> ('a signal -> 'a 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 :After

`sf s`

is applied,`s'`

does not depend on a value that is in a step and`s`

has no dependents in a step (e.g in the simple case where`fix`

is applied outside a step).In that case if the initial value of

`s'`

differs from`i`

,`s`

and its dependents need to be updated and a special update step will be triggered for this. Values depending on the result`r`

will be created only after this special update step has finished (e.g. they won't see the`i`

of`s`

if`r = s`

).- Otherwise, values depending on
`r`

will be created in the same step as`s`

and`s'`

(e.g. they will see the`i`

of`s`

if`r = s`

).

- [

## Lifting

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 signal -> 'b signal`

`val l2 : ?eq:('c -> 'c -> bool) -> ('a -> 'b -> 'c) -> 'a signal -> 'b signal -> 'c signal`

`val l3 : ?eq:('d -> 'd -> bool) -> ('a -> 'b -> 'c -> 'd) -> 'a signal -> 'b signal -> 'c signal -> 'd signal`

`val l4 : ?eq:('e -> 'e -> bool) -> ('a -> 'b -> 'c -> 'd -> 'e) -> 'a signal -> 'b signal -> 'c signal -> 'd signal -> 'e signal`

`val l5 : ?eq:('f -> 'f -> bool) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f) -> 'a signal -> 'b signal -> 'c signal -> 'd signal -> 'e signal -> 'f signal`

`val l6 : ?eq:('g -> 'g -> bool) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g) -> 'a signal -> 'b signal -> 'c signal -> 'd signal -> 'e signal -> 'f signal -> 'g signal`

`module Bool : sig ... end`

`module Int : sig ... end`

`module Float : sig ... end`

`module Pair : sig ... end`

`module Option : sig ... end`

`module Compare : sig ... end`

## Combinator specialization

Given an equality function `equal`

and a type `t`

, the functor `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 `Special`

, open this module to use them.

`module Make : functor (Eq : EqType) -> S with type 'a v = 'a Eq.t`

Functor specializing the combinators for the given signal value type

`module Special : sig ... end`

Specialization for booleans, integers and floats.