]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/fwd/concept/comonad.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / fwd / concept / comonad.hpp
1 /*!
2 @file
3 Forward declares `boost::hana::Comonad`.
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_CONCEPT_COMONAD_HPP
11 #define BOOST_HANA_FWD_CONCEPT_COMONAD_HPP
12
13 #include <boost/hana/config.hpp>
14
15
16 BOOST_HANA_NAMESPACE_BEGIN
17 // Note: We use a multiline C++ comment because there's a double backslash
18 // symbol in the documentation (for LaTeX), which triggers
19 // warning: multi-line comment [-Wcomment]
20 // on GCC.
21
22 /*!
23 @ingroup group-concepts
24 @defgroup group-Comonad Comonad
25 The `Comonad` concept represents context-sensitive computations and
26 data.
27
28 Formally, the Comonad concept is dual to the Monad concept.
29 But unless you're a mathematician, you don't care about that and it's
30 fine. So intuitively, a Comonad represents context sensitive values
31 and computations. First, Comonads make it possible to extract
32 context-sensitive values from their context with `extract`.
33 In contrast, Monads make it possible to wrap raw values into
34 a given context with `lift` (from Applicative).
35
36 Secondly, Comonads make it possible to apply context-sensitive values
37 to functions accepting those, and to return the result as a
38 context-sensitive value using `extend`. In contrast, Monads make
39 it possible to apply a monadic value to a function accepting a normal
40 value and returning a monadic value, and to return the result as a
41 monadic value (with `chain`).
42
43 Finally, Comonads make it possible to wrap a context-sensitive value
44 into an extra layer of context using `duplicate`, while Monads make
45 it possible to take a value with an extra layer of context and to
46 strip it with `flatten`.
47
48 Whereas `lift`, `chain` and `flatten` from Applicative and Monad have
49 signatures
50 \f{align*}{
51 \mathtt{lift}_M &: T \to M(T) \\
52 \mathtt{chain} &: M(T) \times (T \to M(U)) \to M(U) \\
53 \mathtt{flatten} &: M(M(T)) \to M(T)
54 \f}
55
56 `extract`, `extend` and `duplicate` from Comonad have signatures
57 \f{align*}{
58 \mathtt{extract} &: W(T) \to T \\
59 \mathtt{extend} &: W(T) \times (W(T) \to U) \to W(U) \\
60 \mathtt{duplicate} &: W(T) \to W(W(T))
61 \f}
62
63 Notice how the "arrows" are reversed. This symmetry is essentially
64 what we mean by Comonad being the _dual_ of Monad.
65
66 @note
67 The [Typeclassopedia][1] is a nice Haskell-oriented resource for further
68 reading about Comonads.
69
70
71 Minimal complete definition
72 ---------------------------
73 `extract` and (`extend` or `duplicate`) satisfying the laws below.
74 A `Comonad` must also be a `Functor`.
75
76
77 Laws
78 ----
79 For all Comonads `w`, the following laws must be satisfied:
80 @code
81 extract(duplicate(w)) == w
82 transform(duplicate(w), extract) == w
83 duplicate(duplicate(w)) == transform(duplicate(w), duplicate)
84 @endcode
85
86 @note
87 There are several equivalent ways of defining Comonads, and this one
88 is just one that was picked arbitrarily for simplicity.
89
90
91 Refined concept
92 ---------------
93 1. Functor\n
94 Every Comonad is also required to be a Functor. At first, one might think
95 that it should instead be some imaginary concept CoFunctor. However, it
96 turns out that a CoFunctor is the same as a `Functor`, hence the
97 requirement that a `Comonad` also is a `Functor`.
98
99
100 Concrete models
101 ---------------
102 `hana::lazy`
103
104 [1]: https://wiki.haskell.org/Typeclassopedia#Comonad
105
106 */
107 template <typename W>
108 struct Comonad;
109 BOOST_HANA_NAMESPACE_END
110
111 #endif // !BOOST_HANA_FWD_CONCEPT_COMONAD_HPP