<p><code><aclass="el"href="structboost_1_1hana_1_1lazy.html"title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code> implements superficial laziness via a monadic interface. </p>
<p>It is important to understand that the laziness implemented by <code>lazy</code> is only superficial; only function applications made inside the <code>lazy</code> monad can be made lazy, not all their subexpressions.</p>
<dlclass="section note"><dt>Note</dt><dd>The actual representation of <code><aclass="el"href="structboost_1_1hana_1_1lazy.html"title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code> is completely implementation-defined. Lazy values may only be created through <code>hana::make_lazy</code>, and they can be stored in variables using <code>auto</code>, but any other assumption about the representation of <code><aclass="el"href="structboost_1_1hana_1_1lazy.html"title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a><...></code> should be avoided. In particular, one should not rely on the fact that <code><aclass="el"href="structboost_1_1hana_1_1lazy.html"title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a><...></code> can be pattern-matched on, because it may be a dependent type.</dd></dl>
Applying a function over a lazy value with <code>transform</code> returns the result of applying the function, as a lazy value. <divclass="fragment"><divclass="line"><spanclass="comment">// Copyright Louis Dionne 2013-2017</span></div>
<divclass="line"><spanclass="comment">// Distributed under the Boost Software License, Version 1.0.</span></div>
<divclass="line"><spanclass="comment">// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)</span></div>
<divclass="line"> hana::transform(hana::make_lazy(4 / <aclass="code"href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>)(0), <aclass="code"href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a> * 3); <spanclass="comment">// never evaluated</span></div>
<divclass="line">}</div>
</div><!-- fragment --></li>
<li><code>Applicative</code><br/>
A normal value can be lifted into a lazy value by using <code>lift<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>></code>. A lazy function can be lazily applied to a lazy value by using <code>ap</code>.</li>
<li><code>Monad</code><br/>
The <code>lazy</code> monad allows combining lazy computations into larger lazy computations. Note that the <code>|</code> operator can be used in place of the <code>chain</code> function. <divclass="fragment"><divclass="line"><spanclass="comment">// Copyright Louis Dionne 2013-2017</span></div>
<divclass="line"><spanclass="comment">// Distributed under the Boost Software License, Version 1.0.</span></div>
<divclass="line"><spanclass="comment">// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)</span></div>
<divclass="line"> std::cout <<<spanclass="stringliteral">"read "</span><< x <<<spanclass="stringliteral">" from the stream\n"</span>;</div>
<divclass="line"> std::cout <<<spanclass="stringliteral">"putting "</span><<<aclass="code"href="group__group-_searchable.html#ga0d9456ceda38b6ca664998e79d7c45b7">in</a><<<spanclass="stringliteral">" in the stream...\n"</span>;</div>
<divclass="line"> ss <<<aclass="code"href="group__group-_searchable.html#ga0d9456ceda38b6ca664998e79d7c45b7">in</a>; <spanclass="comment">// nothing is evaluated yet</span></div>
<divclass="line"></div>
<divclass="line"> std::cout <<<spanclass="stringliteral">"evaluating the monadic chain...\n"</span>;</div>
<divclass="line"> std::cout <<<spanclass="stringliteral">"the result of the monadic chain is "</span><< eout <<<spanclass="stringliteral">"\n"</span>;</div>
The <code>lazy</code> comonad allows evaluating a lazy computation to get its result and lazily applying functions taking lazy inputs to lazy values. This <ahref="http://ldionne.com/2015/03/16/laziness-as-a-comonad">blog post</a> goes into more details about lazy evaluation and comonads. <divclass="fragment"><divclass="line"><spanclass="comment">// Copyright Louis Dionne 2013-2017</span></div>
<divclass="line"><spanclass="comment">// Distributed under the Boost Software License, Version 1.0.</span></div>
<divclass="line"><spanclass="comment">// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)</span></div>
<dlclass="section note"><dt>Note</dt><dd><code><aclass="el"href="structboost_1_1hana_1_1lazy.html"title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code> 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. </dd></dl>
<trclass="memdesc:aae2998c08f1f80ed52a6acf57c4eec6c"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Evaluate a lazy value and return it. <ahref="structboost_1_1hana_1_1lazy.html#aae2998c08f1f80ed52a6acf57c4eec6c">More...</a><br/></td></tr>
<trclass="memdesc:aa968ecf473c93821f1726fd9692e97f3"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Lifts a normal value to a lazy one. <ahref="structboost_1_1hana_1_1lazy.html#aa968ecf473c93821f1726fd9692e97f3">More...</a><br/></td></tr>
<trclass="memdesc:a7dc86ca61b84fc42aabb525787ae61b4"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Alias to <code>make<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>></code>; provided for convenience. <ahref="structboost_1_1hana_1_1lazy.html#a7dc86ca61b84fc42aabb525787ae61b4">More...</a><br/></td></tr>
<trclass="memdesc:a0527aedd89d16220a6b70404d4b1a322"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Equivalent to <code>hana::chain</code>. <br/></td></tr>
<p>Given a lazy expression <code>expr</code>, <code>eval</code> evaluates <code>expr</code> and returns the result as a normal value. However, for convenience, <code>eval</code> can also be used with nullary and unary function objects. Specifically, if <code>expr</code> is not a <code><aclass="el"href="structboost_1_1hana_1_1lazy.html"title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code>, it is called with no arguments at all and the result of that call (<code>expr()</code>) is returned. Otherwise, if <code>expr()</code> is ill-formed, then <code>expr(hana::id)</code> is returned instead. If that expression is ill-formed, then a compile-time error is triggered.</p>
<p>The reason for allowing nullary callables in <code>eval</code> is because this allows using nullary lambdas as lazy branches to <code>eval_if</code>, which is convenient. The reason for allowing unary callables and calling them with <code><aclass="el"href="group__group-functional.html#gaef38cf34324c8edbd3597ae71811d00d"title="The identity function – returns its argument unchanged.">hana::id</a></code> is because this allows deferring the compile-time evaluation of selected expressions inside the callable. How this can be achieved is documented by <code><aclass="el"href="group__group-_logical.html#gab64636f84de983575aac0208f5fa840c"title="Conditionally execute one of two branches based on a condition.">hana::eval_if</a></code>.</p>
<h2><aclass="anchor"id="autotoc_md222"></a>
Example</h2>
<divclass="fragment"><divclass="line"><spanclass="comment">// Copyright Louis Dionne 2013-2017</span></div>
<divclass="line"><spanclass="comment">// Distributed under the Boost Software License, Version 1.0.</span></div>
<divclass="line"><spanclass="comment">// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)</span></div>
<tdclass="memname">constexpr auto <aclass="el"href="group__group-core.html#ga1d92480f0af1029878e773dafa3e2f60">make</a><<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html">lazy_tag</a>></td>
<p><code>make<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>></code> can be used to lift a normal value or a function call into a lazy expression. Precisely, <code>make<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>>(x)</code> is a lazy value equal to <code>x</code>, and <code>make<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>>(f)(x1, ..., xN)</code> is a lazy function call that is equal to <code>f(x1, ..., xN)</code> when it is <code>eval</code>uated.</p>
<dlclass="section note"><dt>Note</dt><dd>It is interesting to note that <code>make<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>>(f)(x1, ..., xN)</code> is equivalent to <divclass="fragment"><divclass="line">ap(<aclass="code"href="structboost_1_1hana_1_1lazy.html#aa968ecf473c93821f1726fd9692e97f3">make<lazy_tag></a>(f), lift<lazy_tag>(x1), ..., lift<lazy_tag>(xN))</div>
</div><!-- fragment --> which in turn is equivalent to <code>make<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>>(f(x1, ..., xN))</code>, except for the fact that the inner call to <code>f</code> is evaluated lazily.</dd></dl>
<h2><aclass="anchor"id="autotoc_md259"></a>
Example</h2>
<divclass="fragment"><divclass="line"><spanclass="comment">// Copyright Louis Dionne 2013-2017</span></div>
<divclass="line"><spanclass="comment">// Distributed under the Boost Software License, Version 1.0.</span></div>
<divclass="line"><spanclass="comment">// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)</span></div>
<tdclass="memname">constexpr auto make_lazy = <aclass="el"href="group__group-core.html#ga1d92480f0af1029878e773dafa3e2f60">make</a><<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html">lazy_tag</a>></td>
<p>Alias to <code>make<<aclass="el"href="structboost_1_1hana_1_1lazy__tag.html"title="Tag representing hana::lazy.">lazy_tag</a>></code>; provided for convenience. </p>
<h2><aclass="anchor"id="autotoc_md260"></a>
Example</h2>
<divclass="fragment"><divclass="line"><spanclass="comment">// Copyright Louis Dionne 2013-2017</span></div>
<divclass="line"><spanclass="comment">// Distributed under the Boost Software License, Version 1.0.</span></div>
<divclass="line"><spanclass="comment">// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)</span></div>
<divclass="ttc"id="astructboost_1_1hana_1_1lazy_html_aa968ecf473c93821f1726fd9692e97f3"><divclass="ttname"><ahref="structboost_1_1hana_1_1lazy.html#aa968ecf473c93821f1726fd9692e97f3">boost::hana::lazy::make< lazy_tag ></a></div><divclass="ttdeci">constexpr auto make< lazy_tag ></div><divclass="ttdoc">Lifts a normal value to a lazy one.</div><divclass="ttdef"><b>Definition:</b> lazy.hpp:110</div></div>
<divclass="ttc"id="aconfig_8hpp_html"><divclass="ttname"><ahref="config_8hpp.html">config.hpp</a></div><divclass="ttdoc">Defines configuration macros used throughout the library.</div></div>
<divclass="ttc"id="abool_8hpp_html"><divclass="ttname"><ahref="bool_8hpp.html">bool.hpp</a></div><divclass="ttdoc">Defines the Logical and Comparable models of boost::hana::integral_constant.</div></div>
<divclass="ttc"id="agroup__group-_logical_html_gafd655d2222367131e7a63616e93dd080"><divclass="ttname"><ahref="group__group-_logical.html#gafd655d2222367131e7a63616e93dd080">boost::hana::if_</a></div><divclass="ttdeci">constexpr auto if_</div><divclass="ttdoc">Conditionally return one of two values based on a condition.</div><divclass="ttdef"><b>Definition:</b> if.hpp:41</div></div>
<divclass="ttc"id="agroup__group-functional_html_gaefe9fd152cba94be71c2b5b9de689d23"><divclass="ttname"><ahref="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">boost::hana::_</a></div><divclass="ttdeci">constexpr unspecified _</div><divclass="ttdoc">Create simple functions representing C++ operators inline.</div><divclass="ttdef"><b>Definition:</b> placeholder.hpp:70</div></div>
<divclass="ttc"id="agroup__group-assertions_html_gac7aafc41e4dcc7d1f1929fb00f010d2a"><divclass="ttname"><ahref="group__group-assertions.html#gac7aafc41e4dcc7d1f1929fb00f010d2a">BOOST_HANA_CONSTEXPR_CHECK</a></div><divclass="ttdeci">#define BOOST_HANA_CONSTEXPR_CHECK(...)</div><divclass="ttdoc">Equivalent to BOOST_HANA_CONSTEXPR_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERT...</div><divclass="ttdef"><b>Definition:</b> assert.hpp:300</div></div>
<divclass="ttc"id="anamespaceboost_1_1hana_html"><divclass="ttname"><ahref="namespaceboost_1_1hana.html">boost::hana</a></div><divclass="ttdoc">Namespace containing everything in the library.</div><divclass="ttdef"><b>Definition:</b> accessors.hpp:20</div></div>
<divclass="ttc"id="agroup__group-_searchable_html_ga0d9456ceda38b6ca664998e79d7c45b7"><divclass="ttname"><ahref="group__group-_searchable.html#ga0d9456ceda38b6ca664998e79d7c45b7">boost::hana::in</a></div><divclass="ttdeci">constexpr auto in</div><divclass="ttdoc">Return whether the key occurs in the structure.</div><divclass="ttdef"><b>Definition:</b> contains.hpp:70</div></div>
<divclass="ttc"id="aassert_8hpp_html"><divclass="ttname"><ahref="assert_8hpp.html">assert.hpp</a></div><divclass="ttdoc">Defines macros to perform different kinds of assertions.</div></div>
<divclass="ttc"id="agroup__group-assertions_html_ga4796ae107d58b67e0bbccd5ae6f70101"><divclass="ttname"><ahref="group__group-assertions.html#ga4796ae107d58b67e0bbccd5ae6f70101">BOOST_HANA_RUNTIME_CHECK</a></div><divclass="ttdeci">#define BOOST_HANA_RUNTIME_CHECK(...)</div><divclass="ttdoc">Equivalent to BOOST_HANA_RUNTIME_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIO...</div><divclass="ttdef"><b>Definition:</b> assert.hpp:209</div></div>