comonad.hpp 3.7 KB

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