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::lazyis 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.
transformreturns the result of applying the function, as a lazy value.
lift<lazy_tag>. A lazy function can be lazily applied to a lazy value by using
lazymonad allows combining lazy computations into larger lazy computations. Note that the
|operator can be used in place of the
lazycomonad 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::lazyonly 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.
|Evaluate a lazy value and return it. More...|
|constexpr auto||make< lazy_tag >|
|Lifts a normal value to a lazy one. More...|
|constexpr auto||make_lazy = make<lazy_tag>|
|Alias to |
|template<typename... T, typename F >|
|constexpr auto||operator| (lazy< T... >, F)|
|Equivalent to |
Evaluate a lazy value and return it.
Given a lazy expression
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
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
make<lazy_tag>(f)(x1, ..., xN) is a lazy function call that is equal to
f(x1, ..., xN) when it is
make<lazy_tag>(f)(x1, ..., xN)is equivalent to
make<lazy_tag>(f(x1, ..., xN)), except for the fact that the inner call to
fis evaluated lazily.
make<lazy_tag>; provided for convenience.