lwd/lib/lwd/lwd.mli

131 lines
4.3 KiB
OCaml
Raw Normal View History

2020-04-30 11:54:59 +02:00
type +'a t
2020-03-09 05:48:52 +01:00
(** 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 sub-documents are.
- variables {!var}, a mutable reference.
- primitive documents {!prim}, providing custom leaves to trees of
documents.
*)
2019-12-12 11:36:58 +01:00
val return : 'a -> 'a t
2020-03-09 05:48:52 +01:00
(** The content document with the given value inside *)
2019-12-12 11:36:58 +01:00
val pure : 'a -> 'a t
2020-03-09 05:48:52 +01:00
(** Alias to {!return} *)
2019-12-12 11:36:58 +01:00
val map : ('a -> 'b) -> 'a t -> 'b t
2020-03-09 05:48:52 +01:00
(** [map f d] is the document that has value [f x] whenever [d] has value [x] *)
2019-12-12 11:36:58 +01:00
val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
2020-03-09 05:48:52 +01:00
(** [map2 f d1 d2] is the document that has value [f x y] whenever
[d1] has value [x1] and [d2] has value [x2] *)
2019-12-12 11:36:58 +01:00
val map' : 'a t -> ('a -> 'b) -> 'b t
2020-03-09 05:48:52 +01:00
(** Alias to {!map} with arguments flipped *)
2019-12-12 11:36:58 +01:00
val map2' : 'a t -> 'b t -> ('a -> 'b -> 'c) -> 'c t
2020-03-09 05:48:52 +01:00
(** Alias to {!map2} with arguments flipped *)
2019-12-12 11:36:58 +01:00
val join : 'a t t -> 'a t
2020-03-09 05:48:52 +01:00
(** Monadic operator [join d] is the document pointed to by document [d].
This is powerful but potentially costly in case of recomputation.
*)
2019-12-12 11:36:58 +01:00
val bind : 'a t -> ('a -> 'b t) -> 'b t
2020-03-09 05:48:52 +01:00
(** Monadic bind, a mix of {!join} and {!map} *)
2019-12-12 11:36:58 +01:00
val app : ('a -> 'b) t -> 'a t -> 'b t
2020-03-09 05:48:52 +01:00
(** Applicative: [app df dx] is the document that has value [f x]
whenever [df] has value [f] and [dx] has value [x] *)
2019-12-12 11:36:58 +01:00
val pair : 'a t -> 'b t -> ('a * 'b) t
2020-03-09 05:48:52 +01:00
(** [pair a b] is [map2 (fun x y->x,y) a b] *)
2019-12-12 11:36:58 +01:00
val impure : 'a t -> 'a t
2019-12-12 11:36:58 +01:00
type 'a var
2020-03-09 05:48:52 +01:00
(** 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. *)
2019-12-12 11:36:58 +01:00
val var : 'a -> 'a var
2020-03-09 05:48:52 +01:00
(** Create a new variable with the given initial value *)
2019-12-12 11:36:58 +01:00
val get : 'a var -> 'a t
2020-03-09 05:48:52 +01:00
(** A document that reflects the current content of a variable *)
2019-12-12 11:36:58 +01:00
val set : 'a var -> 'a -> unit
2020-03-09 05:48:52 +01:00
(** 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. *)
2019-12-12 11:36:58 +01:00
2020-04-30 11:54:59 +02:00
type +'a prim
2020-03-09 05:48:52 +01:00
(** 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. *)
2019-12-12 11:36:58 +01:00
val prim : acquire:(unit -> 'a) -> release:('a -> unit) -> 'a prim
2020-03-09 05:48:52 +01:00
(** 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. *)
2019-12-12 11:36:58 +01:00
val get_prim : 'a prim -> 'a t
val invalidate : 'a prim -> unit
2020-03-24 20:11:39 +01:00
(** Releasing unused graphs *)
2019-12-12 11:36:58 +01:00
type release_failure = exn * Printexc.raw_backtrace
2020-03-24 20:11:39 +01:00
exception Release_failure of exn option * release_failure list
type release_queue
val make_release_queue : unit -> release_queue
val flush_release_queue : release_queue -> release_failure list
2019-12-12 11:36:58 +01:00
2020-04-30 11:54:59 +02:00
type +'a root
2020-03-09 05:48:52 +01:00
(** A root of computation, whose value(s) over time we're interested in. *)
2019-12-12 11:36:58 +01:00
val observe : ?on_invalidate:('a -> unit) -> 'a t -> 'a root
2020-03-09 05:48:52 +01:00
(** [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 side-effects such as re-rendering some UI. *)
2019-12-12 11:36:58 +01:00
val set_on_invalidate : 'a root -> ('a -> unit) -> unit
2020-03-09 05:48:52 +01:00
(** Change the callback for the root.
@see observe for more details. *)
2019-12-12 11:36:58 +01:00
2020-03-24 20:11:39 +01:00
val sample : release_queue -> 'a root -> 'a
2020-03-09 05:48:52 +01:00
(** Force the computation of the value for this root.
The value is cached, so this is idempotent, until the next invalidation. *)
2019-12-12 11:36:58 +01:00
val is_damaged : 'a root -> bool
2020-03-09 05:48:52 +01:00
(** [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. *)
2020-03-24 20:11:39 +01:00
val release : release_queue -> 'a root -> unit
2020-03-09 05:48:52 +01:00
(** Forget about this root and release sub-values no longer reachable from
any root. *)
2020-03-11 17:18:57 +01:00
2020-03-24 20:11:39 +01:00
val quick_sample : 'a root -> 'a
val quick_release : 'a root -> unit
2020-03-11 17:18:57 +01:00
module Infix : sig
val (>|=) : 'a t -> ('a -> 'b) -> 'b t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
end