applicative.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*!
  2. @file
  3. Forward declares `boost::hana::Applicative`.
  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_APPLICATIVE_HPP
  9. #define BOOST_HANA_FWD_CONCEPT_APPLICATIVE_HPP
  10. #include <boost/hana/config.hpp>
  11. namespace boost { namespace hana {
  12. //! @ingroup group-concepts
  13. //! @defgroup group-Applicative Applicative
  14. //! The `Applicative` concept represents `Functor`s with the ability
  15. //! to lift values and combine computations.
  16. //!
  17. //! A `Functor` can only take a normal function and map it over a
  18. //! structure containing values to obtain a new structure containing
  19. //! values. Intuitively, an `Applicative` can also take a value and
  20. //! lift it into the structure. In addition, an `Applicative` can take
  21. //! a structure containing functions and apply it to a structure
  22. //! containing values to obtain a new structure containing values.
  23. //! By currying the function(s) inside the structure, it is then
  24. //! also possible to apply n-ary functions to n structures containing
  25. //! values.
  26. //!
  27. //! @note
  28. //! This documentation does not go into much details about the nature
  29. //! of applicatives. However, the [Typeclassopedia][1] is a nice
  30. //! Haskell-oriented resource where such information can be found.
  31. //!
  32. //!
  33. //! Minimal complete definition
  34. //! ---------------------------
  35. //! `lift` and `ap` satisfying the laws below. An `Applicative` must
  36. //! also be a `Functor`.
  37. //!
  38. //!
  39. //! Laws
  40. //! ----
  41. //! Given an `Applicative` `F`, the following laws must be satisfied:
  42. //! 1. Identity\n
  43. //! For all objects `xs` of tag `F(A)`,
  44. //! @code
  45. //! ap(lift<F>(id), xs) == xs
  46. //! @endcode
  47. //!
  48. //! 2. Composition\n
  49. //! For all objects `xs` of tag `F(A)` and functions-in-an-applicative
  50. //! @f$ fs : F(B \to C) @f$,
  51. //! @f$ gs : F(A \to B) @f$,
  52. //! @code
  53. //! ap(ap(lift<F>(compose), fs, gs), xs) == ap(fs, ap(gs, xs))
  54. //! @endcode
  55. //!
  56. //! 3. Homomorphism\n
  57. //! For all objects `x` of tag `A` and functions @f$ f : A \to B @f$,
  58. //! @code
  59. //! ap(lift<F>(f), lift<F>(x)) == lift<F>(f(x))
  60. //! @endcode
  61. //!
  62. //! 4. Interchange\n
  63. //! For all objects `x` of tag `A` and functions-in-an-applicative
  64. //! @f$ fs : F(A \to B) @f$,
  65. //! @code
  66. //! ap(fs, lift<F>(x)) == ap(lift<F>(apply(-, x)), fs)
  67. //! @endcode
  68. //! where `apply(-, x)` denotes the partial application of the `apply`
  69. //! function from the @ref group-functional module to the `x` argument.
  70. //!
  71. //! As a consequence of these laws, the model of `Functor` for `F` will
  72. //! satisfy the following for all objects `xs` of tag `F(A)` and functions
  73. //! @f$ f : A \to B @f$:
  74. //! @code
  75. //! transform(xs, f) == ap(lift<F>(f), xs)
  76. //! @endcode
  77. //!
  78. //!
  79. //! Refined concept
  80. //! ---------------
  81. //! 1. `Functor` (free model)\n
  82. //! As a consequence of the laws, any `Applicative F` can be made a
  83. //! `Functor` by setting
  84. //! @code
  85. //! transform(xs, f) = ap(lift<F>(f), xs)
  86. //! @endcode
  87. //!
  88. //!
  89. //! Concrete models
  90. //! ---------------
  91. //! `hana::lazy`, `hana::optional`, `hana::tuple`
  92. //!
  93. //!
  94. //! @anchor applicative-transformation
  95. //! Structure-preserving functions
  96. //! ------------------------------
  97. //! An _applicative transformation_ is a function @f$ t : F(X) \to G(X) @f$
  98. //! between two Applicatives `F` and `G`, where `X` can be any tag, and
  99. //! which preserves the operations of an Applicative. In other words, for
  100. //! all objects `x` of tag `X`, functions-in-an-applicative
  101. //! @f$ fs : F(X \to Y) @f$ and objects `xs` of tag `F(X)`,
  102. //! @code
  103. //! t(lift<F>(x)) == lift<G>(x)
  104. //! t(ap(fs, xs)) == ap(t(fs), t(xs))
  105. //! @endcode
  106. //!
  107. //! [1]: https://wiki.haskell.org/Typeclassopedia#Applicative
  108. template <typename A>
  109. struct Applicative;
  110. }} // end namespace boost::hana
  111. #endif // !BOOST_HANA_FWD_CONCEPT_APPLICATIVE_HPP