]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/hana/fwd/concept/functor.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / hana / fwd / concept / functor.hpp
1 /*!
2 @file
3 Forward declares `boost::hana::Functor`.
4
5 @copyright Louis Dionne 2013-2017
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_FUNCTOR_HPP
11 #define BOOST_HANA_FWD_CONCEPT_FUNCTOR_HPP
12
13 #include <boost/hana/config.hpp>
14
15
16 BOOST_HANA_NAMESPACE_BEGIN
17 //! @ingroup group-concepts
18 //! @defgroup group-Functor Functor
19 //! The `Functor` concept represents types that can be mapped over.
20 //!
21 //! Intuitively, a [Functor][1] is some kind of box that can hold generic
22 //! data and map a function over this data to create a new, transformed
23 //! box. Because we are only interested in mapping a function over the
24 //! contents of a black box, the only real requirement for being a functor
25 //! is to provide a function which can do the mapping, along with a couple
26 //! of guarantees that the mapping is well-behaved. Those requirements are
27 //! made precise in the laws below. The pattern captured by `Functor` is
28 //! very general, which makes it widely useful. A lot of objects can be
29 //! made `Functor`s in one way or another, the most obvious example being
30 //! sequences with the usual mapping of the function on each element.
31 //! While this documentation will not go into much more details about
32 //! the nature of functors, the [Typeclassopedia][2] is a nice
33 //! Haskell-oriented resource for such information.
34 //!
35 //! Functors are parametric data types which are parameterized over the
36 //! data type of the objects they contain. Like everywhere else in Hana,
37 //! this parametricity is only at the documentation level and it is not
38 //! enforced.
39 //!
40 //! In this library, the mapping function is called `transform` after the
41 //! `std::transform` algorithm, but other programming languages have given
42 //! it different names (usually `map`).
43 //!
44 //! @note
45 //! The word _functor_ comes from functional programming, where the
46 //! concept has been used for a while, notably in the Haskell programming
47 //! language. Haskell people borrowed the term from [category theory][3],
48 //! which, broadly speaking, is a field of mathematics dealing with
49 //! abstract structures and transformations between those structures.
50 //!
51 //!
52 //! Minimal complete definitions
53 //! ----------------------------
54 //! 1. `transform`\n
55 //! When `transform` is specified, `adjust_if` is defined analogously to
56 //! @code
57 //! adjust_if(xs, pred, f) = transform(xs, [](x){
58 //! if pred(x) then f(x) else x
59 //! })
60 //! @endcode
61 //!
62 //! 2. `adjust_if`\n
63 //! When `adjust_if` is specified, `transform` is defined analogously to
64 //! @code
65 //! transform(xs, f) = adjust_if(xs, always(true), f)
66 //! @endcode
67 //!
68 //!
69 //! Laws
70 //! ----
71 //! Let `xs` be a Functor with tag `F(A)`,
72 //! \f$ f : A \to B \f$ and
73 //! \f$ g : B \to C \f$.
74 //! The following laws must be satisfied:
75 //! @code
76 //! transform(xs, id) == xs
77 //! transform(xs, compose(g, f)) == transform(transform(xs, f), g)
78 //! @endcode
79 //! The first line says that mapping the identity function should not do
80 //! anything, which precludes the functor from doing something nasty
81 //! behind the scenes. The second line states that mapping the composition
82 //! of two functions is the same as mapping the first function, and then
83 //! the second on the result. While the usual functor laws are usually
84 //! restricted to the above, this library includes other convenience
85 //! methods and they should satisfy the following equations.
86 //! Let `xs` be a Functor with tag `F(A)`,
87 //! \f$ f : A \to A \f$,
88 //! \f$ \mathrm{pred} : A \to \mathrm{Bool} \f$
89 //! for some `Logical` `Bool`, and `oldval`, `newval`, `value` objects
90 //! of tag `A`. Then,
91 //! @code
92 //! adjust(xs, value, f) == adjust_if(xs, equal.to(value), f)
93 //! adjust_if(xs, pred, f) == transform(xs, [](x){
94 //! if pred(x) then f(x) else x
95 //! })
96 //! replace_if(xs, pred, value) == adjust_if(xs, pred, always(value))
97 //! replace(xs, oldval, newval) == replace_if(xs, equal.to(oldval), newval)
98 //! fill(xs, value) == replace_if(xs, always(true), value)
99 //! @endcode
100 //! The default definition of the methods will satisfy these equations.
101 //!
102 //!
103 //! Concrete models
104 //! ---------------
105 //! `hana::lazy`, `hana::optional`, `hana::tuple`
106 //!
107 //!
108 //! Structure-preserving functions for Functors
109 //! -------------------------------------------
110 //! A mapping between two functors which also preserves the functor
111 //! laws is called a natural transformation (the term comes from
112 //! category theory). A natural transformation is a function `f`
113 //! from a functor `F` to a functor `G` such that for every other
114 //! function `g` with an appropriate signature and for every object
115 //! `xs` of tag `F(X)`,
116 //! @code
117 //! f(transform(xs, g)) == transform(f(xs), g)
118 //! @endcode
119 //!
120 //! There are several examples of such transformations, like `to<tuple_tag>`
121 //! when applied to an optional value. Indeed, for any function `g` and
122 //! `hana::optional` `opt`,
123 //! @code
124 //! to<tuple_tag>(transform(opt, g)) == transform(to<tuple_tag>(opt), g)
125 //! @endcode
126 //!
127 //! Of course, natural transformations are not limited to the `to<...>`
128 //! functions. However, note that any conversion function between Functors
129 //! should be natural for the behavior of the conversion to be intuitive.
130 //!
131 //!
132 //! [1]: http://en.wikipedia.org/wiki/Functor
133 //! [2]: https://wiki.haskell.org/Typeclassopedia#Functor
134 //! [3]: http://en.wikipedia.org/wiki/Category_theory
135 template <typename F>
136 struct Functor;
137 BOOST_HANA_NAMESPACE_END
138
139 #endif // !BOOST_HANA_FWD_CONCEPT_FUNCTOR_HPP