An observer lets one get the value of an incremental, either by asking directly for the value or installing an on-update handler to run when the incremental's value changes.
One first creates an observer using observe
. One must then call stabilize
before making any observations on that observer.
Doing let o = observe t
causes subsequent calls to stabilize
to maintain the
value of t
, until either:
disallow_future_use o
is called, oro
is garbage collected and o
has no on-update handlers.include sig ... end
val sexp_of_t : ('a ‑> Base.Sexp.t) ‑> 'a t ‑> Base.Sexp.t
include Core_kernel.Invariant.S1 with type a t := a t
val invariant : 'a Base__.Invariant_intf.inv ‑> 'a t Base__.Invariant_intf.inv
val observing : 'a t ‑> 'a incremental
val use_is_allowed : _ t ‑> bool
val value : 'a t ‑> 'a Core_kernel.Or_error.t
value t
returns the current value of t
, or Error
if t
does not currently
have a stable value. In particular, value t
will return Error
in the
following situations:
stabilize
has not been called since t
was created.disallow_future_use t
has been called.observing t
is invalid.Rather than using value
in a function that runs during stabilization, one should
use map
or bind
to express the dependence of an incremental computation on an
incremental.
val value_exn : 'a t ‑> 'a
module Update : sig ... end
on_update_exn t ~f
calls f
after the current stabilization and after each
subsequent stabilization in which t
changes, until disallow_future_use t
is
called. f
will be called at most once per stabilization. Here is a state
diagram for the allowable sequences of Update.t
's that can be supplied to a
particular f
:
val disallow_future_use : _ t ‑> unit
disallow_future_use t
causes all future attempts to use t
to fail and
on_update_exn
handlers added to t
to never run again. It also causes
incremental to treat t
as unobserved, and thus stabilize
will not maintain the
value of t
or any of t
's descendants that are needed only to maintain t
.
disallow_future_use
raises if called during stabilization.