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