module Lazy:`sig`

..`end`

Deferred computations.

type`'a`

t =`'a CamlinternalLazy.t`

A value of type `'a Lazy.t`

is a deferred computation, called a suspension,
that has a result of type `'a`

. The special expression syntax `lazy (expr)`

makes a suspension of the computation of `expr`

, without computing
`expr`

itself yet. "Forcing" the suspension will then compute `expr`

and
return its result. Matching a suspension with the special pattern syntax
`lazy(pattern)`

also computes the underlying expression and tries to bind
it to `pattern`

:

```
let lazy_option_map f x =
match x with
| lazy (Some x) -> Some (Lazy.force f x)
| _ -> None
```

Note: If lazy patterns appear in multiple cases in a pattern-matching, lazy
expressions may be forced even outside of the case ultimately selected by
the pattern matching. In the example above, the suspension `x`

is always
computed.

Note: `lazy_t`

is the built-in type constructor used by the compiler for the
`lazy`

keyword. You should not use it directly. Always use `Lazy.t`

instead.

Note: `Lazy.force`

is not concurrency-safe. If you use this module with
multiple fibers, systhreads or domains, then you will need to add some
locks. The module however ensures memory-safety, and hence, concurrently
accessing this module will not lead to a crash but the behaviour is
unspecified.

Note: if the program is compiled with the `-rectypes`

option,
ill-founded recursive definitions of the form `let rec x = lazy x`

or `let rec x = lazy(lazy(...(lazy x)))`

are accepted by the type-checker
and lead, when forced, to ill-formed values that trigger infinite
loops in the garbage collector and other parts of the run-time system.
Without the `-rectypes`

option, such ill-founded recursive definitions
are rejected by the type-checker.

`exception Undefined`

Raised when forcing a suspension concurrently from multiple fibers, systhreads or domains, or when the suspension tries to force itself recursively.

`val force : ``'a t -> 'a`

`force x`

forces the suspension `x`

and returns its result. If `x`

has
already been forced, `Lazy.force x`

returns the same value again without
recomputing it. If it raised an exception, the same exception is raised
again.

**Raises**`Undefined`

(see`Lazy.Undefined`

).

`val map : ``('a -> 'b) -> 'a t -> 'b t`

`map f x`

returns a suspension that, when forced,
forces `x`

and applies `f`

to its value.

It is equivalent to `lazy (f (Lazy.force x))`

.

**Since**4.13

`val is_val : ``'a t -> bool`

`is_val x`

returns `true`

if `x`

has already been forced and
did not raise an exception.

**Since**4.00

`val from_val : ``'a -> 'a t`

`from_val v`

evaluates `v`

first (as any function would) and returns
an already-forced suspension of its result.
It is the same as `let x = v in lazy x`

, but uses dynamic tests
to optimize suspension creation in some cases.

**Since**4.00

`val map_val : ``('a -> 'b) -> 'a t -> 'b t`

`map_val f x`

applies `f`

directly if `x`

is already forced,
otherwise it behaves as `map f x`

.

When `x`

is already forced, this behavior saves the construction of
a suspension, but on the other hand it performs more work eagerly
that may not be useful if you never force the function result.

If `f`

raises an exception, it will be raised immediately when
`is_val x`

, or raised only when forcing the thunk otherwise.

If `map_val f x`

does not raise an exception, then
`is_val (map_val f x)`

is equal to `is_val x`

.

**Since**4.13

The following definitions are for advanced uses only; they require familiary with the lazy compilation scheme to be used appropriately.

`val from_fun : ``(unit -> 'a) -> 'a t`

`from_fun f`

is the same as `lazy (f ())`

but slightly more efficient.

It should only be used if the function `f`

is already defined.
In particular it is always less efficient to write
`from_fun (fun () -> expr)`

than `lazy expr`

.

**Since**4.00

`val force_val : ``'a t -> 'a`

`force_val x`

forces the suspension `x`

and returns its result. If `x`

has already been forced, `force_val x`

returns the same value again
without recomputing it.

If the computation of `x`

raises an exception, it is unspecified
whether `force_val x`

raises the same exception or `Lazy.Undefined`

.

**Raises**`Undefined`

if the forcing of`x`

tries to force`x`

itself recursively.`Undefined`

(see`Lazy.Undefined`

).