|
||||
File indexing completed on 2025-01-18 09:37:58
0001 /*! 0002 @file 0003 Forward declares `boost::hana::Comonad`. 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_CONCEPT_COMONAD_HPP 0011 #define BOOST_HANA_FWD_CONCEPT_COMONAD_HPP 0012 0013 #include <boost/hana/config.hpp> 0014 0015 0016 namespace boost { namespace hana { 0017 // Note: We use a multiline C++ comment because there's a double backslash 0018 // symbol in the documentation (for LaTeX), which triggers 0019 // warning: multi-line comment [-Wcomment] 0020 // on GCC. 0021 0022 /*! 0023 @ingroup group-concepts 0024 @defgroup group-Comonad Comonad 0025 The `Comonad` concept represents context-sensitive computations and 0026 data. 0027 0028 Formally, the Comonad concept is dual to the Monad concept. 0029 But unless you're a mathematician, you don't care about that and it's 0030 fine. So intuitively, a Comonad represents context sensitive values 0031 and computations. First, Comonads make it possible to extract 0032 context-sensitive values from their context with `extract`. 0033 In contrast, Monads make it possible to wrap raw values into 0034 a given context with `lift` (from Applicative). 0035 0036 Secondly, Comonads make it possible to apply context-sensitive values 0037 to functions accepting those, and to return the result as a 0038 context-sensitive value using `extend`. In contrast, Monads make 0039 it possible to apply a monadic value to a function accepting a normal 0040 value and returning a monadic value, and to return the result as a 0041 monadic value (with `chain`). 0042 0043 Finally, Comonads make it possible to wrap a context-sensitive value 0044 into an extra layer of context using `duplicate`, while Monads make 0045 it possible to take a value with an extra layer of context and to 0046 strip it with `flatten`. 0047 0048 Whereas `lift`, `chain` and `flatten` from Applicative and Monad have 0049 signatures 0050 \f{align*}{ 0051 \mathtt{lift}_M &: T \to M(T) \\ 0052 \mathtt{chain} &: M(T) \times (T \to M(U)) \to M(U) \\ 0053 \mathtt{flatten} &: M(M(T)) \to M(T) 0054 \f} 0055 0056 `extract`, `extend` and `duplicate` from Comonad have signatures 0057 \f{align*}{ 0058 \mathtt{extract} &: W(T) \to T \\ 0059 \mathtt{extend} &: W(T) \times (W(T) \to U) \to W(U) \\ 0060 \mathtt{duplicate} &: W(T) \to W(W(T)) 0061 \f} 0062 0063 Notice how the "arrows" are reversed. This symmetry is essentially 0064 what we mean by Comonad being the _dual_ of Monad. 0065 0066 @note 0067 The [Typeclassopedia][1] is a nice Haskell-oriented resource for further 0068 reading about Comonads. 0069 0070 0071 Minimal complete definition 0072 --------------------------- 0073 `extract` and (`extend` or `duplicate`) satisfying the laws below. 0074 A `Comonad` must also be a `Functor`. 0075 0076 0077 Laws 0078 ---- 0079 For all Comonads `w`, the following laws must be satisfied: 0080 @code 0081 extract(duplicate(w)) == w 0082 transform(duplicate(w), extract) == w 0083 duplicate(duplicate(w)) == transform(duplicate(w), duplicate) 0084 @endcode 0085 0086 @note 0087 There are several equivalent ways of defining Comonads, and this one 0088 is just one that was picked arbitrarily for simplicity. 0089 0090 0091 Refined concept 0092 --------------- 0093 1. Functor\n 0094 Every Comonad is also required to be a Functor. At first, one might think 0095 that it should instead be some imaginary concept CoFunctor. However, it 0096 turns out that a CoFunctor is the same as a `Functor`, hence the 0097 requirement that a `Comonad` also is a `Functor`. 0098 0099 0100 Concrete models 0101 --------------- 0102 `hana::lazy` 0103 0104 [1]: https://wiki.haskell.org/Typeclassopedia#Comonad 0105 0106 */ 0107 template <typename W> 0108 struct Comonad; 0109 }} // end namespace boost::hana 0110 0111 #endif // !BOOST_HANA_FWD_CONCEPT_COMONAD_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |