Module Note.S

Signals.

A signal is a value that varies continuously over time. It has a value at every point in time.

Signals

type 'a t = 'a signal

The type for signals of type 'a.

type 'a set = ?⁠step:Step.t -> 'a -> unit

The type for functions setting signal values of type 'a. See create.

val obs : 'a t -> 'a Logr.obs

obs s is an observation for s.

val log : ?⁠now:bool -> 'a signal -> ('a -> unit) -> Logr.t

log ?now s f is Logr.(create ~now (const f $ obs s)).

val create : ?⁠eq:('a -> 'a -> bool) -> 'a -> 'a signal * 'a set

create v is a primitive signal set to the value v 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.
  • set ~step v sets the signal value to v at the time it is called and schedules an update at time step.

Warning. set must not be used in the definition of signals or events.

val eq : 'a signal -> 'a -> 'a -> bool

eq s is s's equality function.

val with_eq : ('a -> 'a -> bool) -> 'a signal -> 'a signal

with_eq eq s is s with equality function eq.

val value : 'a signal -> 'a

value s is the current value of s, [s]t

val rough_value : 'a signal -> 'a

rough_value s is the current value of s, but in contrast to value it might not be exactly [s]t.

val const : ?⁠eq:('a -> 'a -> bool) -> 'a -> 'a signal

const v is always v, [const v]t = v.

val hold : ?⁠eq:('a -> 'a -> bool) -> 'a -> 'a event -> 'a signal

hold i e has the value of e's last occurrence or the value of i provides the signal value at creation time if there's no event at that time.

  • [hold i e]t = i if [e]<=t = None
  • [hold i e]t = v if [e]<=t = Some v
val bind : 'a signal -> ('a -> 'b signal) -> 'b signal

bind s f is the signal that results from applying f to s, [bind s f]t = [f[s]t]t.

val join : 'a signal signal -> 'a signal

join ss is bind ss (fun s -> s).

val swap : 'a signal -> 'a signal event -> 'a signal

swap s se is join (hold ~eq:( == ) s se) that is the values of s followed by values of the last signal that occured on se.

val changes : 'a signal -> 'a event

changes s occurs with the value of s whenever it changes.

  • [changes s]t = Some v if [s]t = v and [s]t-dt = v' and eq v v' = false.
  • [changes s]t = None otherwise.

Warning. By definition no event occurs if s changes at creation time (0 - dt is undefined).

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 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 sample : 'b signal -> on:'a event -> ('b -> 'a -> 'c) -> 'c event

sample s ~on f samples s at e's occurrences.

  • [sample s ~on f]t = Some (f sv ev) if [on]t = Some ev and [s]t = sv.
  • [sample s ~on f]t = None otherwise.
val sample_filter : 'b signal -> on:'a event -> ('b -> 'a -> 'c option) -> 'c event

sample_filter s on f is E.Option.on_some (sample s ~on f).

val snapshot : 'b signal -> on:'a event -> 'b event

snapshot ~on s is sample (fun v _ -> v) ~on s.

TODO. Candidate for deletion.

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

accum i e is hold i (E.accum i e).

val until : ?⁠limit:bool -> ?⁠init:'b -> next:'a event -> 'b signal -> 'b signal

until ~limit ~init ~next s is s until next occurs, after which the value s had just before (limit is false, default) or whenever next occurs (limit is true) is kept forever.

  • [until ~limit ~init ~next s]t = [s]t if [next]<=t = None
  • [until ~limit ~init ~next s]t = init if [next]0 = Some _
  • [until ~limit:false ~init ~next s]t = [s]t'- dt if [next]t' = Some _ and [next]<t' = None.
  • [until ~limit:true ~init ~next s]t = [s]t' if [next]t' = Some _ and [next]<t' = None.

init defaults to value s.

val follow : ?⁠init:'a -> 'a signal -> on:bool signal -> 'a signal

follow ~init s ~on is s whenever on is true and the last value of s when on was true if on is false. If on is false at creation time init is used (defaults to S.value s).

  • [follow ~init s ~on]0 = [s]0 if [on]0 = true
  • [follow ~init s ~on]0 = [init]0 if [on]0 = false
  • [follow ~init s ~on]t = [s]t if [on]t = true
  • [follow ~init s ~on]t = [follow ~init s ~on]t' if [on]t = false where t' is the greatest t' < t with [on]t' = true or 0 if there is no such time.
val defer : ?⁠init:'a -> 'a signal -> 'a signal

defer s is s delayed by an infinitesimal amount of time. At creation time init is used (defaults to S.value s).

  • [defer s]t = init for t = 0.
  • [defer s]t = [s]t-dt otherwise.
val delay : 'a -> 'a signal Stdlib.Lazy.t -> 'a signal

delay i (lazy s) is the value s had an infinitesimal amount of time before:

  • [delay i (lazy s)]t = i for t = 0.
  • [delay i (lazy s)]t = [s']t-dt otherwise.
val fix : ?⁠eq:('a -> 'a -> bool) -> 'a -> ('a signal -> 'a signal * 'b) -> 'b

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.

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

Stdlib types support

module Bool : sig ... end

Boolean signals

module Option : sig ... end

Option signals

module Pair : sig ... end

Pair signals.