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.Functortransform returns the result of applying the function, as a lazy value. Applicativelift<lazy_tag>. A lazy function can be lazily applied to a lazy value by using ap.Monadlazy monad allows combining lazy computations into larger lazy computations. Note that the | operator can be used in place of the chain function. Comonadlazy 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 evaluated.
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.