Module Deferred

module Deferred: sig .. end
A deferred is 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 Ivar.Deferred.t 
A deferred is 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 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
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.

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 determined
val 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
Like all, but ignores results of the component deferreds
val any : 'a t list -> 'a t
any ts returns a deferred that is fulfilled when any of the underlying deferreds is fulfilled
val any_unit : 'a t list -> unit t
any_unit ts like any but ignores results of the component deferreds
module 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
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.
include Raw
The Raw interface exposed here is for async's internal use only. It must be exported here because we want the Deferred.t type to be fully abstract, so that they shows up nicely in type errors, yet other async code defined later needs to deal with the raw type.
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.

The Raw interface exposed here is for async's internal use only. It must be exported here because we want the Deferred.t type to be fully abstract, so that they shows up nicely in type errors, yet other async code defined later needs to deal with the raw type.