* A delayed computation that can produce a deferred . 

     Nothing happens with a lazy deferred unless one [ force]s 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 ) in 
     ] } 

     There 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 ] .

    Nothing happens with a lazy deferred unless one [force]s 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) in
    ]}

    There 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]. *)

open! Core

type 'a t

(** [create 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
  :  ?rest_exn:[ `Call of exn -> unit | `Log | `Raise ]
  -> (unit -> 'a Deferred.t)
  -> 'a t

* Same as { ! create } but allows [ f ] to explicitly return errors as well as 
     raise . The two cases are joined and not distingused in the result of 
     { ! force } . 

     If an exception is raised by [ f ] asynchronously after its result is determined , 
     [ rest_exn ] specifies how to handle the exception .
    raise. The two cases are joined and not distingused in the result of
    {!force}.

    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 t

(** [force t] forces evaluation of [t] and returns a deferred that becomes determined
    when the deferred computation becomes determined or raises. *)
val force : 'a t -> 'a Or_error.t Deferred.t

val force_exn : 'a t -> 'a Deferred.t

(** [wait t] and [wait_exn t] waits for [t] to be forced.  If no one ever calls
    [force t], they will wait forever. *)
val wait : 'a t -> 'a Or_error.t Deferred.t

val wait_exn : 'a t -> 'a Deferred.t

(** 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 Monad with type 'a t := 'a t

(** [bind'] differs from [bind] in that the supplied function produces an ['a Deferred.t]
    rather than an ['a t]. *)
val bind' : 'a t -> ('a -> 'b Deferred.t) -> 'b t

(** Read-only operations. *)

(** [peek t = Deferred.peek (wait t)] *)
val peek : 'a t -> 'a Or_error.t option

val peek_exn : 'a t -> 'a option
val is_determined : _ t -> bool
val is_forced : _ t -> bool

* [create 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. 
* [force 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. 
* [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)] 
* A delayed computation that can produce a deferred . 

     Nothing happens with a lazy deferred unless one [ force]s 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 ) in 
     ] } 

     There 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 ] .

    Nothing happens with a lazy deferred unless one [force]s 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) in
    ]}

    There 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]. *)

open! Core

type 'a t

val create
  :  ?rest_exn:[ `Call of exn -> unit | `Log | `Raise ]
  -> (unit -> 'a Deferred.t)
  -> 'a t

* Same as { ! create } but allows [ f ] to explicitly return errors as well as 
     raise . The two cases are joined and not distingused in the result of 
     { ! force } . 

     If an exception is raised by [ f ] asynchronously after its result is determined , 
     [ rest_exn ] specifies how to handle the exception .
    raise. The two cases are joined and not distingused in the result of
    {!force}.

    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 t

val force : 'a t -> 'a Or_error.t Deferred.t

val force_exn : 'a t -> 'a Deferred.t

val wait : 'a t -> 'a Or_error.t Deferred.t

val wait_exn : 'a t -> 'a Deferred.t


include Monad with type 'a t := 'a t

val bind' : 'a t -> ('a -> 'b Deferred.t) -> 'b t


val peek : 'a t -> 'a Or_error.t option

val peek_exn : 'a t -> 'a option
val is_determined : _ t -> bool
val is_forced : _ t -> bool
