hana::lazy
implements superficial laziness via a monadic interface.
It is important to understand that the laziness implemented by lazy
is only superficial; only function applications made inside the lazy
monad can be made lazy, not all their subexpressions.
hana::lazy
is completely implementation-defined. Lazy values may only be created through hana::make_lazy
, and they can be stored in variables using auto
, but any other assumption about the representation of hana::lazy<...>
should be avoided. In particular, one should not rely on the fact that hana::lazy<...>
can be pattern-matched on, because it may be a dependent type.Functor
transform
returns the result of applying the function, as a lazy value. Applicative
lift<lazy_tag>
. A lazy function can be lazily applied to a lazy value by using ap
.Monad
lazy
monad allows combining lazy computations into larger lazy computations. Note that the |
operator can be used in place of the chain
function. Comonad
lazy
comonad allows evaluating a lazy computation to get its result and lazily applying functions taking lazy inputs to lazy values. This blog post goes into more details about lazy evaluation and comonads. hana::lazy
only models a few concepts because providing more functionality would require evaluating the lazy values in most cases. Since this raises some issues such as side effects and memoization, the interface is kept minimal. Synopsis of associated functions | |
constexpr auto | eval |
Evaluate a lazy value and return it. More... | |
template<> | |
constexpr auto | make< lazy_tag > |
Lifts a normal value to a lazy one. More... | |
constexpr auto | make_lazy = make<lazy_tag> |
Alias to make<lazy_tag> ; provided for convenience. More... | |
Friends | |
template<typename... T, typename F > | |
constexpr auto | operator| (lazy< T... >, F) |
Equivalent to hana::chain . | |
|
related |
Evaluate a lazy value and return it.
Given a lazy expression expr
, eval
evaluates expr
and returns the result as a normal value. However, for convenience, eval
can also be used with nullary and unary function objects. Specifically, if expr
is not a hana::lazy
, it is called with no arguments at all and the result of that call (expr()
) is returned. Otherwise, if expr()
is ill-formed, then expr(hana::id)
is returned instead. If that expression is ill-formed, then a compile-time error is triggered.
The reason for allowing nullary callables in eval
is because this allows using nullary lambdas as lazy branches to eval_if
, which is convenient. The reason for allowing unary callables and calling them with hana::id
is because this allows deferring the compile-time evaluation of selected expressions inside the callable. How this can be achieved is documented by hana::eval_if
.
Lifts a normal value to a lazy one.
make<lazy_tag>
can be used to lift a normal value or a function call into a lazy expression. Precisely, make<lazy_tag>(x)
is a lazy value equal to x
, and make<lazy_tag>(f)(x1, ..., xN)
is a lazy function call that is equal to f(x1, ..., xN)
when it is eval
uated.
make<lazy_tag>(f)(x1, ..., xN)
is equivalent to make<lazy_tag>(f(x1, ..., xN))
, except for the fact that the inner call to f
is evaluated lazily.Alias to make<lazy_tag>
; provided for convenience.