module Deferred: Deferred
type'a
t =('a, Execution_context.t) Raw_deferred.t
val sexp_of_t : ('a -> Sexplib.Sexp.t) -> 'a t -> Sexplib.Sexp.t
type'a
detailed ='a t
val sexp_of_detailed : ('a -> Sexplib.Sexp.t) -> 'a detailed -> Sexplib.Sexp.t
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 t_of_sexp
.
val create : ('a Ivar.t -> unit) -> 'a t
create f
calls f i
, where i
is empty ivar. create
returns a deferred that
becomes determined when f
fills i
.val upon : 'a t -> ('a -> unit) -> unit
upon t f
will run f v
at some point after t
becomes determined with value
v
.val peek : 'a t -> 'a option
peek t
returns Some v
iff t
is determined with value t
.val is_determined : 'a t -> bool
is_determined t
returns true
iff t
is determined.include Monad
t >>= f
returns a deferred t' that waits until t is determined to have
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.
Note that
upon t f
is more efficient than
ignore (t >>= (fun a -> f a; Deferred.unit))
because upon
, unlike >>=
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 () ... )
The same loop written with >>=
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 >>=
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.
module Infix:sig
..end
val unit : unit t
unit
is a deferred that is always determined with value ()
val never : unit -> 'a t
never ()
returns a deferred that never becomes determinedval both : 'a t -> 'b t -> ('a * 'b) t
both t1 t2
becomes determined after both t1
and t2
become determined.val all : 'a t list -> 'a list t
all ts
returns a deferred that becomes determined when every t in ts
is determined. The output is in the same order as the input.val all_unit : unit t list -> unit t
all
, but ignores results of the component deferredsmodule Array:Deferred_sequence
with type 'a t = 'a array
module List:Deferred_sequence
with type 'a t = 'a list
module Queue:Deferred_sequence
with type 'a t = 'a Queue.t
module Map:Deferred_map
with type ('k, 'v) t = ('k, 'v) Map.Poly.t
val whenever : unit t -> unit
whenever t
ignores t completely. It is like Fn.ignore
, but is
more constrained because it requires a deferred.
If you want to ignore t : 'a t
, then do whenever (Deferred.ignore t)
.
We chose to give whenever
type unit t
rather than 'a t
to catch errors
where a value is accidentally ignored.
type 'a
choice
choice
is used to produce an argument to enabled
or choose
. See below.val choice : 'a t -> ('a -> 'b) -> 'b choice
val enabled : 'b choice list -> (unit -> 'b list) t
enabled [choice t1 f1; ... choice tn fn;]
returns a deferred d
that becomes
determined when any of the ti
become determined. The value of d
is a function f
that when called, for each ti
that is enabled, applies fi
to 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.val choose : 'b choice list -> 'b t
choose choices
is enabled choices >>| (fun f -> List.hd_exn (f ()))
.
That is:
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
. 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, if you write
choose choice t1 (fun () -> `X1);
choice t2 (fun () -> `X2);
>>> function
| `X1 -> e1
| `X2 -> e2
It may be the case that both d1
and d2
become determined, yet the code
e2
actually runs.
val choose_ident : 'a t list -> 'a t
choose_ident l
= choose (List.map l ~f:(fun t -> choice t ident))
. That is,
choose_ident
is a choice among deferreds of the same type.val repeat_until_finished : 'state ->
('state -> [ `Finished of 'result | `Repeat of 'state ] t) ->
'result t
repeat_until_finished initial_state f
repeatedly runs f
until f
returns
`Finished
. The first call to f
happens immediately when repeat_until_finished
is called.val debug_space_leaks : int option Pervasives.ref
debug_space_leaks
to Some n
to trigger assertion failures when single deferred
has more than n
handlers waiting for it to be filled. Note that if n
is
less than 2, we may not trigger all assertion failures.