module Deferred:sig
..end
type'a
t ='a Ivar.Deferred.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 deferredsval any : 'a t list -> 'a t
any ts
returns a deferred that is fulfilled when any of the underlying deferreds is
fulfilledval any_unit : 'a t list -> unit t
any_unit ts
like any
but ignores results of the component deferredsmodule type Monad_sequence =Monad_sequence
with type 'a monad := 'a t
module Array:Monad_sequence
with type 'a t = 'a array
module List:Monad_sequence
with type 'a t = 'a list
module Queue:Monad_sequence
with type 'a t = 'a Queue.t
module Map:Deferred_intf.Deferred_map
module Result:Monad.S2
with type ('a, 'b) t = ('a, 'b) Result.t t
module Option:Monad.S
with type 'a t = 'a option t
val don't_wait_for : unit t -> unit
don't_wait_for t
ignores t completely. It is like Fn.ignore
, but is more
constrained because it requires a unit Deferred.t
.
Rather than ignore (t : _ t)
, do don't_wait_for (Deferred.ignore t)
.
We chose to give don't_wait_for
type unit t
rather than _ 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 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 forever : 'state -> ('state -> 'state t) -> unit
forever initial_state f
repeatedly runs f
, supplying the state returned to the
next call to f
.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.val sexp_of_t : ('a -> Sexplib.Sexp.t) -> 'a t -> 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
.
create f
calls f i
, where i
is empty ivar. create
returns a deferred that
becomes determined when f
fills i
.
upon t f
will run f v
at some point after t
becomes determined with value
v
.
peek t
returns Some v
iff t
is determined with value t
.
is_determined t
returns true
iff t
is determined.
Deferreds form a 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.
unit
is a deferred that is always determined with value ()
never ()
returns a deferred that never becomes determined
both t1 t2
becomes determined after both t1
and t2
become determined.
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.
Like all
, but ignores results of the component deferreds
any ts
returns a deferred that is fulfilled when any of the underlying deferreds is
fulfilled
any_unit ts
like any
but ignores results of the component deferreds
don't_wait_for t
ignores t completely. It is like Fn.ignore
, but is more
constrained because it requires a unit Deferred.t
.
Rather than ignore (t : _ t)
, do don't_wait_for (Deferred.ignore t)
.
We chose to give don't_wait_for
type unit t
rather than _ t
to catch errors
where a value is accidentally ignored.
choice
is used to produce an argument to enabled
or choose
. See below.
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.
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.
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.
forever initial_state f
repeatedly runs f
, supplying the state returned to the
next call to f
.
Set 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.