Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:53:04

0001 /*!
0002 @file
0003 Forward declares `boost::hana::lazy`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_FWD_LAZY_HPP
0011 #define BOOST_HANA_FWD_LAZY_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 #include <boost/hana/fwd/core/make.hpp>
0015 
0016 
0017 namespace boost { namespace hana {
0018     //! @ingroup group-datatypes
0019     //! `hana::lazy` implements superficial laziness via a monadic interface.
0020     //!
0021     //! It is important to understand that the laziness implemented by `lazy`
0022     //! is only superficial; only function applications made inside the `lazy`
0023     //! monad can be made lazy, not all their subexpressions.
0024     //!
0025     //!
0026     //! @note
0027     //! The actual representation of `hana::lazy` is completely
0028     //! implementation-defined. Lazy values may only be created through
0029     //! `hana::make_lazy`, and they can be stored in variables using
0030     //! `auto`, but any other assumption about the representation of
0031     //! `hana::lazy<...>` should be avoided. In particular, one should
0032     //! not rely on the fact that `hana::lazy<...>` can be pattern-matched
0033     //! on, because it may be a dependent type.
0034     //!
0035     //!
0036     //! Modeled concepts
0037     //! ----------------
0038     //! 1. `Functor`\n
0039     //! Applying a function over a lazy value with `transform` returns the
0040     //! result of applying the function, as a lazy value.
0041     //! @include example/lazy/functor.cpp
0042     //!
0043     //! 2. `Applicative`\n
0044     //! A normal value can be lifted into a lazy value by using `lift<lazy_tag>`.
0045     //! A lazy function can be lazily applied to a lazy value by using `ap`.
0046     //!
0047     //! 3. `Monad`\n
0048     //! The `lazy` monad allows combining lazy computations into larger
0049     //! lazy computations. Note that the `|` operator can be used in place
0050     //! of the `chain` function.
0051     //! @include example/lazy/monad.cpp
0052     //!
0053     //! 4. `Comonad`\n
0054     //! The `lazy` comonad allows evaluating a lazy computation to get its
0055     //! result and lazily applying functions taking lazy inputs to lazy
0056     //! values. This [blog post][1]  goes into more details about lazy
0057     //! evaluation and comonads.
0058     //! @include example/lazy/comonad.cpp
0059     //!
0060     //!
0061     //! @note
0062     //! `hana::lazy` only models a few concepts because providing more
0063     //! functionality would require evaluating the lazy values in most cases.
0064     //! Since this raises some issues such as side effects and memoization,
0065     //! the interface is kept minimal.
0066     //!
0067     //!
0068     //! [1]: http://ldionne.com/2015/03/16/laziness-as-a-comonad
0069 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0070     template <typename implementation_defined>
0071     struct lazy {
0072         //! Equivalent to `hana::chain`.
0073         template <typename ...T, typename F>
0074         friend constexpr auto operator|(lazy<T...>, F);
0075     };
0076 #else
0077     // We do not _actually_ define the lazy<...> type. Per the documentation,
0078     // users can't rely on it being anything, and so they should never use
0079     // it explicitly. The implementation in <boost/hana/lazy.hpp> is much
0080     // simpler if we use different types for lazy calls and lazy values.
0081 #endif
0082 
0083     //! Tag representing `hana::lazy`.
0084     //! @relates hana::lazy
0085     struct lazy_tag { };
0086 
0087     //! Lifts a normal value to a lazy one.
0088     //! @relates hana::lazy
0089     //!
0090     //! `make<lazy_tag>` can be used to lift a normal value or a function call
0091     //! into a lazy expression. Precisely, `make<lazy_tag>(x)` is a lazy value
0092     //! equal to `x`, and `make<lazy_tag>(f)(x1, ..., xN)` is a lazy function
0093     //! call that is equal to `f(x1, ..., xN)` when it is `eval`uated.
0094     //!
0095     //! @note
0096     //! It is interesting to note that `make<lazy_tag>(f)(x1, ..., xN)` is
0097     //! equivalent to
0098     //! @code
0099     //!     ap(make<lazy_tag>(f), lift<lazy_tag>(x1), ..., lift<lazy_tag>(xN))
0100     //! @endcode
0101     //! which in turn is equivalent to `make<lazy_tag>(f(x1, ..., xN))`, except
0102     //! for the fact that the inner call to `f` is evaluated lazily.
0103     //!
0104     //!
0105     //! Example
0106     //! -------
0107     //! @include example/lazy/make.cpp
0108 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0109     template <>
0110     constexpr auto make<lazy_tag> = [](auto&& x) {
0111         return lazy<implementation_defined>{forwarded(x)};
0112     };
0113 #endif
0114 
0115     //! Alias to `make<lazy_tag>`; provided for convenience.
0116     //! @relates hana::lazy
0117     //!
0118     //! Example
0119     //! -------
0120     //! @include example/lazy/make.cpp
0121     BOOST_HANA_INLINE_VARIABLE constexpr auto make_lazy = make<lazy_tag>;
0122 }} // end namespace boost::hana
0123 
0124 #endif // !BOOST_HANA_FWD_LAZY_HPP