Module Async_kernel.Deferred
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.
type +'a t
= 'a Async_kernel__.Deferred1.t
val sexp_of_t : ('a -> Ppx_sexp_conv_lib.Sexp.t) -> 'a t -> Ppx_sexp_conv_lib.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 create : ('a Ivar.t -> unit) -> 'a t
create f
callsf i
, wherei
is an empty ivar.create
returns a deferred that becomes determined whenf
fillsi
.
val upon : 'a t -> ('a -> unit) -> unit
upon t f
will runf v
at some point aftert
becomes determined with valuev
.
val peek : 'a t -> 'a option
peek t
returnsSome v
ifft
is determined with valuev
.
val value_exn : 'a t -> 'a
value_exn t
returnsv
ift
is determined with valuev
, and raises otherwise.
val is_determined : 'a t -> bool
is_determined t
returnstrue
ifft
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.
Note that:
upon t f
is more efficient than:
ignore (let%bind a = t in f a; return ())
because upon
, unlike 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 () ... )
although often forever
or 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
include Base__.Monad_intf.S_without_syntax with type 'a t := 'a t
module Monad_infix : Base__.Monad_intf.Infix with type 'a t := 'a t
val return : 'a -> 'a t
return v
returns the (trivial) computation that returns v.
val ignore_m : 'a t -> unit t
ignore_m t
ismap t ~f:(fun _ -> ())
.ignore_m
used to be calledignore
, but we decided that was a bad name, because it shadowed the widely usedCaml.ignore
. Some monads still dolet ignore = ignore_m
for historical reasons.
module Infix : sig ... end
val unit : unit t
unit
is a deferred that is always determined with value()
val ignore : _ t -> unit t
val never : unit -> _ t
never ()
returns a deferred that never becomes determined.
val both : 'a t -> 'b t -> ('a * 'b) t
both t1 t2
becomes determined after botht1
andt2
become determined.
val all : 'a t list -> 'a list t
all ts
returns a deferred that becomes determined when everyt
int
s is determined. The output is in the same order as the input.
val any : 'a t list -> 'a t
any ts
returns a deferred that is determined when any of the underlying deferreds is determined.
val any_unit : unit t list -> unit t
any_unit
is likeany
, but ignores results of the component deferreds.
val don't_wait_for : unit t -> unit
don't_wait_for t
ignorest
. It is likeFn.ignore
, but is more constrained because it requires aunit Deferred.t
.Rather than
ignore (t : _ t)
, dodon't_wait_for (Deferred.ignore t)
.We chose to give
don't_wait_for
typeunit t
rather than_ t
to catch errors where a value is accidentally ignored.
module Choice : sig ... end
A
Choice.t
is used to produce an argument toenabled
orchoose
. See below.
type 'a choice
= 'a Choice.t
val choice : 'a t -> ('a -> 'b) -> 'b Choice.t
val enabled : 'b Choice.t list -> (unit -> 'b list) t
enabled [choice t1 f1; ... choice tn fn;]
returns a deferredd
that becomes determined when any of theti
becomes determined. The value ofd
is a functionf
that when called, for eachti
that is enabled, appliesfi
toti
, and returns a list of the results. It is guaranteed that the list is in the same order as the choices supplied toenabled
, but of course it may be shorter than the input list if not allti
are determined.
val choose : 'b Choice.t list -> 'b t
choose [ choice t1 f1 ; ... ; choice tn fn ]
returns a deferred
t
that becomes determined with valuefi ai
after someti
becomes determined with valueai
. It is guaranteed thatchoose
calls at most one of thefi
s, the one that determines its result. There is no guarantee that theti
that becomes determined earliest in time will be the one whose value determines thechoose
. Nor is it guaranteed that the value int
is the first value (in place order) fromchoices
that is determined at the timet
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
t1
andt2
become determined, yete2
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
choose
.
val for_ : int -> to_:int -> do_:(int -> unit t) -> unit t
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 runsf
untilf
returns`Finished
. The first call tof
happens immediately whenrepeat_until_finished
is called.
val forever : 'state -> ('state -> 'state t) -> unit
forever initial_state f
repeatedly runsf
, supplying the state returned to the next call tof
.
val ok : 'a t -> ('a, _) Core_kernel.Result.t t
Useful for lifting values from the
Deferred.t
monad to theResult.t Deferred.t
monad.
Deferred collections
These contain operations for iterating in a deferred manner over different collection types.
module Array = Async_kernel__.Deferred_array
module List = Async_kernel__.Deferred_list
module Map = Async_kernel__.Deferred_map
module Memo = Async_kernel__.Deferred_memo
module Queue = Async_kernel__.Deferred_queue
module Sequence = Async_kernel__.Deferred_sequence
Error-carrying deferreds
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 = Async_kernel__.Deferred_option
module Or_error = Async_kernel__.Deferred_or_error
module Result = Async_kernel__.Deferred_result