Async_kernel.Lazy_deferredSourceA delayed computation that can produce a deferred.
Nothing happens with a lazy deferred unless one forces it. Forcing a lazy deferred starts the computation, which will eventually cause the deferred to become determined. As usual with laziness, multiply forcing a lazy deferred is no different than forcing it a single time.
Exceptions (both synchronous and asynchronous) raised by a delayed computation are returned by force (wait, peek, etc.), or will be raised to the monitor in effect when force_exn (wait_exn, peek_exn, etc.) was called.
The type is not exposed nor defined as 'a Deferred.t Lazy.t or 'a Or_error.t Deferred.t Lazy.t, because there is a difference in power with these types. Any value of type 'a Deferred.t Lazy.t would mishandle asynchronous exceptions in the computation of 'a. For instance, the following code blocks forever regardless of how v is defined:
let v : Nothing.t Deferred.t Lazy.t = lazy (return "" >>| failwith) in
let%bind _ = try_with (fun () -> force v) in
let%bind _ = try_with (fun () -> force v) inThere is no val of_lazy : 'a Deferred.t Lazy.t -> 'a t because of the difference in power.
See also Deferred.Memo.unit, if you only are interested in create and force.
val create :
?rest_exn:[ `Call of exn -> unit | `Log | `Raise ] ->
(unit -> 'a Deferred.t) ->
'a tcreate f creates a new lazy deferred that will call f when it is forced.
If an exception is raised by f asynchronously after its result is determined, rest_exn specifies how to handle the exception.
val create_or_error :
?rest_exn:[ `Call of exn -> unit | `Log | `Raise ] ->
(unit -> 'a Deferred.Or_error.t) ->
'a tforce t forces evaluation of t and returns a deferred that becomes determined when the deferred computation becomes determined or raises.
wait t and wait_exn t waits for t to be forced. If no one ever calls force t, they will wait forever.
This monad is designed to let you write as though you are in a lazy language, where all computations only run when needed (forced). If your use case just has a few lazy computations and you want to reason about them the same way you reason about regular deferreds (where map/bind means run the next step once the previous is determined), see Laziness_preserving_deferred.
bind t f in the lazy-deferred monad creates a computation that, when forced, will force t, apply f to the result, and then force the result of that.
include Core.Monad with type 'a t := 'a tt >>= 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 f 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 Stdlib.ignore. Some monads still do let ignore = ignore_m for historical reasons.
Like all, but ensures that every monadic value in the list produces a unit value, all of which are discarded rather than being collected into a list.
These are convenient to have in scope when programming with a monad:
bind' differs from bind in that the supplied function produces an 'a Deferred.t rather than an 'a t.
Read-only operations.
peek t = Deferred.peek (wait t)