]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/fwd/lazy.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / fwd / lazy.hpp
1 /*!
2 @file
3 Forward declares `boost::hana::lazy`.
4
5 @copyright Louis Dionne 2013-2016
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10 #ifndef BOOST_HANA_FWD_LAZY_HPP
11 #define BOOST_HANA_FWD_LAZY_HPP
12
13 #include <boost/hana/config.hpp>
14 #include <boost/hana/fwd/core/make.hpp>
15
16
17 BOOST_HANA_NAMESPACE_BEGIN
18 //! @ingroup group-datatypes
19 //! `hana::lazy` implements superficial laziness via a monadic interface.
20 //!
21 //! It is important to understand that the laziness implemented by `lazy`
22 //! is only superficial; only function applications made inside the `lazy`
23 //! monad can be made lazy, not all their subexpressions.
24 //!
25 //!
26 //! @note
27 //! The actual representation of `hana::lazy` is completely
28 //! implementation-defined. Lazy values may only be created through
29 //! `hana::make_lazy`, and they can be stored in variables using
30 //! `auto`, but any other assumption about the representation of
31 //! `hana::lazy<...>` should be avoided. In particular, one should
32 //! not rely on the fact that `hana::lazy<...>` can be pattern-matched
33 //! on, because it may be a dependent type.
34 //!
35 //!
36 //! Modeled concepts
37 //! ----------------
38 //! 1. `Functor`\n
39 //! Applying a function over a lazy value with `transform` returns the
40 //! result of applying the function, as a lazy value.
41 //! @include example/lazy/functor.cpp
42 //!
43 //! 2. `Applicative`\n
44 //! A normal value can be lifted into a lazy value by using `lift<lazy_tag>`.
45 //! A lazy function can be lazily applied to a lazy value by using `ap`.
46 //!
47 //! 3. `Monad`\n
48 //! The `lazy` monad allows combining lazy computations into larger
49 //! lazy computations. Note that the `|` operator can be used in place
50 //! of the `chain` function.
51 //! @include example/lazy/monad.cpp
52 //!
53 //! 4. `Comonad`\n
54 //! The `lazy` comonad allows evaluating a lazy computation to get its
55 //! result and lazily applying functions taking lazy inputs to lazy
56 //! values. This [blog post][1] goes into more details about lazy
57 //! evaluation and comonads.
58 //! @include example/lazy/comonad.cpp
59 //!
60 //!
61 //! @note
62 //! `hana::lazy` only models a few concepts because providing more
63 //! functionality would require evaluating the lazy values in most cases.
64 //! Since this raises some issues such as side effects and memoization,
65 //! the interface is kept minimal.
66 //!
67 //!
68 //! [1]: http://ldionne.com/2015/03/16/laziness-as-a-comonad
69 #ifdef BOOST_HANA_DOXYGEN_INVOKED
70 template <typename implementation_defined>
71 struct lazy {
72 //! Equivalent to `hana::chain`.
73 template <typename ...T, typename F>
74 friend constexpr auto operator|(lazy<T...>, F);
75 };
76 #else
77 // We do not _actually_ define the lazy<...> type. Per the documentation,
78 // users can't rely on it being anything, and so they should never use
79 // it explicitly. The implementation in <boost/hana/lazy.hpp> is much
80 // simpler if we use different types for lazy calls and lazy values.
81 #endif
82
83 //! Tag representing `hana::lazy`.
84 //! @relates hana::lazy
85 struct lazy_tag { };
86
87 //! Lifts a normal value to a lazy one.
88 //! @relates hana::lazy
89 //!
90 //! `make<lazy_tag>` can be used to lift a normal value or a function call
91 //! into a lazy expression. Precisely, `make<lazy_tag>(x)` is a lazy value
92 //! equal to `x`, and `make<lazy_tag>(f)(x1, ..., xN)` is a lazy function
93 //! call that is equal to `f(x1, ..., xN)` when it is `eval`uated.
94 //!
95 //! @note
96 //! It is interesting to note that `make<lazy_tag>(f)(x1, ..., xN)` is
97 //! equivalent to
98 //! @code
99 //! ap(make<lazy_tag>(f), lift<lazy_tag>(x1), ..., lift<lazy_tag>(xN))
100 //! @endcode
101 //! which in turn is equivalent to `make<lazy_tag>(f(x1, ..., xN))`, except
102 //! for the fact that the inner call to `f` is evaluated lazily.
103 //!
104 //!
105 //! Example
106 //! -------
107 //! @include example/lazy/make.cpp
108 #ifdef BOOST_HANA_DOXYGEN_INVOKED
109 template <>
110 constexpr auto make<lazy_tag> = [](auto&& x) {
111 return lazy<implementation_defined>{forwarded(x)};
112 };
113 #endif
114
115 //! Alias to `make<lazy_tag>`; provided for convenience.
116 //! @relates hana::lazy
117 //!
118 //! Example
119 //! -------
120 //! @include example/lazy/make.cpp
121 constexpr auto make_lazy = make<lazy_tag>;
122 BOOST_HANA_NAMESPACE_END
123
124 #endif // !BOOST_HANA_FWD_LAZY_HPP