A value that will become determined asynchronously.
A deferred can be "undetermined" or "determined". A deferred that is undetermined may at some point become determined with value v, and will henceforth always be determined with value v.
sexp_of_t t f returns a sexp of the deferred's value, if it is determined, or an informative string otherwise.
This is just for display purposes. There is no
create f calls
f i, where
i is an empty ivar.
create returns a deferred that becomes determined when
val upon : 'a t -> ('a -> unit) -> unit
upon t f will run
f v at some point after
t becomes determined with value
val peek : 'a t -> 'a option
peek t returns
Some v iff
t is determined with value
val value_exn : 'a t -> 'a
value_exn t returns
t is determined with value
v, and raises otherwise.
val is_determined : 'a t -> bool
is_determined t returns
t is determined.
Deferreds form a monad.
let%bind v = t in f v returns a deferred
t' that waits until
t is determined with value
v, at which point it waits for
f v to become determined with value
v', to which
t' will become determined.
return v returns a deferred that is immediately determined with value v.
upon t f
is more efficient than:
ignore (let%bind a = t in f a; return ())
let%bind, does not create a deferred to hold the result.
For example, one can write a loop that has good constant factors with:
let rec loop () = upon t (fun a -> ... loop () ... )
repeat_until_finished is more clear.
The same loop written with
let%bind would allocate deferreds that would be immediately garbage collected. (In the past, this loop would have also used linear space in recursion depth!)
In general, for deferreds that are allocated by
let%bind to be garbage collected quickly, it is sufficient that the allocating bind be executed in tail-call position of the right-hand side of an outer bind.
include Core_kernel.Monad with type 'a t := 'a t
t >>= f returns a computation that sequences the computations represented by two monad elements. The resulting computation first does
t to yield a value
v, and then runs the computation returned by
module Monad_infix : sig ... end
val return : 'a -> 'a t
return v returns the (trivial) computation that returns v.
ignore_m t is
map t ~f:(fun _ -> ()).
ignore_m used to be called
ignore, but we decided that was a bad name, because it shadowed the widely used
Caml.ignore. Some monads still do
let ignore = ignore_m for historical reasons.
module Let_syntax : sig ... end
These are convenient to have in scope when programming with a monad:
module Infix : sig ... end
val unit : unit t
unit is a deferred that is always determined with value
val never : unit -> _ t
never () returns a deferred that never becomes determined.
both t1 t2 becomes determined after both
t2 become determined.
all ts returns a deferred that becomes determined when every
ts is determined. The output is in the same order as the input.
any ts returns a deferred that is determined when any of the underlying deferreds is determined.
any_unit is like
any, but ignores results of the component deferreds.
val don't_wait_for : unit t -> unit
don't_wait_for t ignores
t. It is like
Fn.ignore, but is more constrained because it requires a
ignore (t : _ t), do
don't_wait_for (Deferred.ignore t).
We chose to give
unit t rather than
_ t to catch errors where a value is accidentally ignored.
module Choice : sig ... end
Choice.t is used to produce an argument to
choose. See below.
type 'a choice = 'a Choice.t
enabled [choice t1 f1; ... choice tn fn;] returns a deferred
d that becomes determined when any of the
ti becomes determined. The value of
d is a function
f that when called, for each
ti that is enabled, applies
ti, and returns a list of the results. It is guaranteed that the list is in the same order as the choices supplied to
enabled, but of course it may be shorter than the input list if not all
ti are determined.
choose [ choice t1 f1 ; ... ; choice tn fn ]
returns a deferred
t that becomes determined with value
fi ai after some
ti becomes determined with value
ai. It is guaranteed that
choose calls at most one of the
fis, the one that determines its result. There is no guarantee that the
ti that becomes determined earliest in time will be the one whose value determines the
choose. Nor is it guaranteed that the value in
t is the first value (in place order) from
choices that is determined at the time
t is examined.
For example, in:
choose [ choice t1 (fun () -> `X1) ; choice t2 (fun () -> `X2) ] >>> function | `X1 -> e1 | `X2 -> e2
it may be the case that both
t2 become determined, yet
e2 actually runs.
It is guaranteed that if multiple choices are determined with no intervening asynchrony, then the earliest choice in the list will become the value of the
for_ start ~to_:stop ~do_:f is the deferred analog of:
for i = start to stop do f i; done
val repeat_until_finished : 'state -> ('state -> [ `Repeat of 'state | `Finished of 'result ] t) -> 'result t
repeat_until_finished initial_state f repeatedly runs
`Finished. The first call to
f happens immediately when
repeat_until_finished is called.
val forever : 'state -> ('state -> 'state t) -> unit
forever initial_state f repeatedly runs
f, supplying the state returned to the next call to
Useful for lifting values from the
Deferred.t monad to the
Result.t Deferred.t monad.
These contain operations for iterating in a deferred manner over different collection types.
module Array : sig ... end
module List : sig ... end
module Map : sig ... end
module Memo : sig ... end
Memoization functions like in
Core_kernel.Memo, with re-raising of exceptions thrown asynchronously.
module Queue : sig ... end
Deferred_queue iteration functions first copy the queue (to a list) and then start calling the user function
f. So, if
f modifies the queue, that will have no effect on the iteration.
module Sequence : sig ... end
These contain interfaces for working with deferred type containing error-aware types, like
'a Option.t Deferred.t, or
'a Or_error.t Deferred.t. These all include support for monadic programming.
module Option : sig ... end
module Or_error : sig ... end
The deferred analog of
Core.Or_error. It is exposed in std.ml as
module Result : sig ... end