You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('') and can be up to 35 characters long.
114 lines
3.9 KiB
114 lines
3.9 KiB
type 'a t 

(** A dynamic document of type ['a]. Documents can be produced in several 

different ways: 



 operators, such as {!map}, {!bind}, {!app}, {!pair}, etc. 

combine several documents into one. The result is (lazily) 

updated whenever the subdocuments are. 



 variables {!var}, a mutable reference. 

 primitive documents {!prim}, providing custom leaves to trees of 

documents. 

*) 



val return : 'a > 'a t 

(** The content document with the given value inside *) 



val pure : 'a > 'a t 

(** Alias to {!return} *) 



val map : ('a > 'b) > 'a t > 'b t 

(** [map f d] is the document that has value [f x] whenever [d] has value [x] *) 



val map2 : ('a > 'b > 'c) > 'a t > 'b t > 'c t 

(** [map2 f d1 d2] is the document that has value [f x y] whenever 

[d1] has value [x1] and [d2] has value [x2] *) 



val map' : 'a t > ('a > 'b) > 'b t 

(** Alias to {!map} with arguments flipped *) 



val map2' : 'a t > 'b t > ('a > 'b > 'c) > 'c t 

(** Alias to {!map2} with arguments flipped *) 



val join : 'a t t > 'a t 

(** Monadic operator [join d] is the document pointed to by document [d]. 

This is powerful but potentially costly in case of recomputation. 

*) 



val bind : 'a t > ('a > 'b t) > 'b t 

(** Monadic bind, a mix of {!join} and {!map} *) 



val app : ('a > 'b) t > 'a t > 'b t 

(** Applicative: [app df dx] is the document that has value [f x] 

whenever [df] has value [f] and [dx] has value [x] *) 



val pair : 'a t > 'b t > ('a * 'b) t 

(** [pair a b] is [map2 (fun x y>x,y) a b] *) 



val impure : 'a t > 'a t 



type 'a var 

(** The workhorse of Lwd: a mutable variable that also tracks dependencies. 

Every time {!set} is called, all documents that depend on this variable 

via {!map}, {!bind}, etc. will be at least partially invalidated 

and will be recomputed incrementally on demand. *) 



val var : 'a > 'a var 

(** Create a new variable with the given initial value *) 



val get : 'a var > 'a t 

(** A document that reflects the current content of a variable *) 



val set : 'a var > 'a > unit 

(** Change the variable's content, invalidating all documents depending 

on it. *) 



val peek : 'a var > 'a 

(** Observe the current value of the variable, without any dependency 

tracking. *) 



type 'a prim 

(** A primitive document. It can correspond, for example, to 

a primitive UI element. 



A primitive is a resource with [acquire] and [release] functions 

to manage its lifecycle. *) 



val prim : acquire:(unit > 'a) > release:('a > unit) > 'a prim 

(** create a new primitive document. 

@param acquire is called when the document becomes observed (indirectly) 

via at least one {!root}. 

@param release is called when the document is no longer observed. 

Internal resources can be freed. *) 



val get_prim : 'a prim > 'a t 

val invalidate : 'a prim > unit 



type release_failure = exn * Printexc.raw_backtrace 

exception Release_failure of release_failure list 



type 'a root 

(** A root of computation, whose value(s) over time we're interested in. *) 



val observe : ?on_invalidate:('a > unit) > 'a t > 'a root 

(** [observe x] creates a root that contains document [x]. 

@param on_invalidate is called whenever the root is invalidated 

because the content of [x] has changed. This can be useful to 

perform sideeffects such as rerendering some UI. *) 



val set_on_invalidate : 'a root > ('a > unit) > unit 

(** Change the callback for the root. 

@see observe for more details. *) 



val sample : 'a root > 'a 

(** Force the computation of the value for this root. 

The value is cached, so this is idempotent, until the next invalidation. *) 



val is_damaged : 'a root > bool 

(** [is_damaged root] is true if the root doesn't have a valid value in 

cache. This can be the case if the value was never computed, or 

if it was computed and then invalidated. *) 



val release : 'a root > unit 

(** Forget about this root and release subvalues no longer reachable from 

any root. *)


