| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | /*!@fileForward declares `boost::hana::lazy`.@copyright Louis Dionne 2013-2017Distributed under the Boost Software License, Version 1.0.(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */#ifndef BOOST_HANA_FWD_LAZY_HPP#define BOOST_HANA_FWD_LAZY_HPP#include <boost/hana/config.hpp>#include <boost/hana/fwd/core/make.hpp>BOOST_HANA_NAMESPACE_BEGIN    //! @ingroup group-datatypes    //! `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.    //!    //!    //! @note    //! The actual representation of `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.    //!    //!    //! Modeled concepts    //! ----------------    //! 1. `Functor`\n    //! Applying a function over a lazy value with `transform` returns the    //! result of applying the function, as a lazy value.    //! @include example/lazy/functor.cpp    //!    //! 2. `Applicative`\n    //! A normal value can be lifted into a lazy value by using `lift<lazy_tag>`.    //! A lazy function can be lazily applied to a lazy value by using `ap`.    //!    //! 3. `Monad`\n    //! The `lazy` monad allows combining lazy computations into larger    //! lazy computations. Note that the `|` operator can be used in place    //! of the `chain` function.    //! @include example/lazy/monad.cpp    //!    //! 4. `Comonad`\n    //! The `lazy` comonad allows evaluating a lazy computation to get its    //! result and lazily applying functions taking lazy inputs to lazy    //! values. This [blog post][1]  goes into more details about lazy    //! evaluation and comonads.    //! @include example/lazy/comonad.cpp    //!    //!    //! @note    //! `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.    //!    //!    //! [1]: http://ldionne.com/2015/03/16/laziness-as-a-comonad#ifdef BOOST_HANA_DOXYGEN_INVOKED    template <typename implementation_defined>    struct lazy {        //! Equivalent to `hana::chain`.        template <typename ...T, typename F>        friend constexpr auto operator|(lazy<T...>, F);    };#else    // We do not _actually_ define the lazy<...> type. Per the documentation,    // users can't rely on it being anything, and so they should never use    // it explicitly. The implementation in <boost/hana/lazy.hpp> is much    // simpler if we use different types for lazy calls and lazy values.#endif    //! Tag representing `hana::lazy`.    //! @relates hana::lazy    struct lazy_tag { };    //! Lifts a normal value to a lazy one.    //! @relates hana::lazy    //!    //! `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.    //!    //! @note    //! It is interesting to note that `make<lazy_tag>(f)(x1, ..., xN)` is    //! equivalent to    //! @code    //!     ap(make<lazy_tag>(f), lift<lazy_tag>(x1), ..., lift<lazy_tag>(xN))    //! @endcode    //! which in turn is equivalent to `make<lazy_tag>(f(x1, ..., xN))`, except    //! for the fact that the inner call to `f` is evaluated lazily.    //!    //!    //! Example    //! -------    //! @include example/lazy/make.cpp#ifdef BOOST_HANA_DOXYGEN_INVOKED    template <>    constexpr auto make<lazy_tag> = [](auto&& x) {        return lazy<implementation_defined>{forwarded(x)};    };#endif    //! Alias to `make<lazy_tag>`; provided for convenience.    //! @relates hana::lazy    //!    //! Example    //! -------    //! @include example/lazy/make.cpp    constexpr auto make_lazy = make<lazy_tag>;BOOST_HANA_NAMESPACE_END#endif // !BOOST_HANA_FWD_LAZY_HPP
 |