|
||||
File indexing completed on 2025-01-18 09:37:58
0001 /*! 0002 @file 0003 Forward declares `boost::hana::Functor`. 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_FUNCTOR_HPP 0011 #define BOOST_HANA_FWD_CONCEPT_FUNCTOR_HPP 0012 0013 #include <boost/hana/config.hpp> 0014 0015 0016 namespace boost { namespace hana { 0017 //! @ingroup group-concepts 0018 //! @defgroup group-Functor Functor 0019 //! The `Functor` concept represents types that can be mapped over. 0020 //! 0021 //! Intuitively, a [Functor][1] is some kind of box that can hold generic 0022 //! data and map a function over this data to create a new, transformed 0023 //! box. Because we are only interested in mapping a function over the 0024 //! contents of a black box, the only real requirement for being a functor 0025 //! is to provide a function which can do the mapping, along with a couple 0026 //! of guarantees that the mapping is well-behaved. Those requirements are 0027 //! made precise in the laws below. The pattern captured by `Functor` is 0028 //! very general, which makes it widely useful. A lot of objects can be 0029 //! made `Functor`s in one way or another, the most obvious example being 0030 //! sequences with the usual mapping of the function on each element. 0031 //! While this documentation will not go into much more details about 0032 //! the nature of functors, the [Typeclassopedia][2] is a nice 0033 //! Haskell-oriented resource for such information. 0034 //! 0035 //! Functors are parametric data types which are parameterized over the 0036 //! data type of the objects they contain. Like everywhere else in Hana, 0037 //! this parametricity is only at the documentation level and it is not 0038 //! enforced. 0039 //! 0040 //! In this library, the mapping function is called `transform` after the 0041 //! `std::transform` algorithm, but other programming languages have given 0042 //! it different names (usually `map`). 0043 //! 0044 //! @note 0045 //! The word _functor_ comes from functional programming, where the 0046 //! concept has been used for a while, notably in the Haskell programming 0047 //! language. Haskell people borrowed the term from [category theory][3], 0048 //! which, broadly speaking, is a field of mathematics dealing with 0049 //! abstract structures and transformations between those structures. 0050 //! 0051 //! 0052 //! Minimal complete definitions 0053 //! ---------------------------- 0054 //! 1. `transform`\n 0055 //! When `transform` is specified, `adjust_if` is defined analogously to 0056 //! @code 0057 //! adjust_if(xs, pred, f) = transform(xs, [](x){ 0058 //! if pred(x) then f(x) else x 0059 //! }) 0060 //! @endcode 0061 //! 0062 //! 2. `adjust_if`\n 0063 //! When `adjust_if` is specified, `transform` is defined analogously to 0064 //! @code 0065 //! transform(xs, f) = adjust_if(xs, always(true), f) 0066 //! @endcode 0067 //! 0068 //! 0069 //! Laws 0070 //! ---- 0071 //! Let `xs` be a Functor with tag `F(A)`, 0072 //! \f$ f : A \to B \f$ and 0073 //! \f$ g : B \to C \f$. 0074 //! The following laws must be satisfied: 0075 //! @code 0076 //! transform(xs, id) == xs 0077 //! transform(xs, compose(g, f)) == transform(transform(xs, f), g) 0078 //! @endcode 0079 //! The first line says that mapping the identity function should not do 0080 //! anything, which precludes the functor from doing something nasty 0081 //! behind the scenes. The second line states that mapping the composition 0082 //! of two functions is the same as mapping the first function, and then 0083 //! the second on the result. While the usual functor laws are usually 0084 //! restricted to the above, this library includes other convenience 0085 //! methods and they should satisfy the following equations. 0086 //! Let `xs` be a Functor with tag `F(A)`, 0087 //! \f$ f : A \to A \f$, 0088 //! \f$ \mathrm{pred} : A \to \mathrm{Bool} \f$ 0089 //! for some `Logical` `Bool`, and `oldval`, `newval`, `value` objects 0090 //! of tag `A`. Then, 0091 //! @code 0092 //! adjust(xs, value, f) == adjust_if(xs, equal.to(value), f) 0093 //! adjust_if(xs, pred, f) == transform(xs, [](x){ 0094 //! if pred(x) then f(x) else x 0095 //! }) 0096 //! replace_if(xs, pred, value) == adjust_if(xs, pred, always(value)) 0097 //! replace(xs, oldval, newval) == replace_if(xs, equal.to(oldval), newval) 0098 //! fill(xs, value) == replace_if(xs, always(true), value) 0099 //! @endcode 0100 //! The default definition of the methods will satisfy these equations. 0101 //! 0102 //! 0103 //! Concrete models 0104 //! --------------- 0105 //! `hana::lazy`, `hana::optional`, `hana::tuple` 0106 //! 0107 //! 0108 //! Structure-preserving functions for Functors 0109 //! ------------------------------------------- 0110 //! A mapping between two functors which also preserves the functor 0111 //! laws is called a natural transformation (the term comes from 0112 //! category theory). A natural transformation is a function `f` 0113 //! from a functor `F` to a functor `G` such that for every other 0114 //! function `g` with an appropriate signature and for every object 0115 //! `xs` of tag `F(X)`, 0116 //! @code 0117 //! f(transform(xs, g)) == transform(f(xs), g) 0118 //! @endcode 0119 //! 0120 //! There are several examples of such transformations, like `to<tuple_tag>` 0121 //! when applied to an optional value. Indeed, for any function `g` and 0122 //! `hana::optional` `opt`, 0123 //! @code 0124 //! to<tuple_tag>(transform(opt, g)) == transform(to<tuple_tag>(opt), g) 0125 //! @endcode 0126 //! 0127 //! Of course, natural transformations are not limited to the `to<...>` 0128 //! functions. However, note that any conversion function between Functors 0129 //! should be natural for the behavior of the conversion to be intuitive. 0130 //! 0131 //! 0132 //! [1]: http://en.wikipedia.org/wiki/Functor 0133 //! [2]: https://wiki.haskell.org/Typeclassopedia#Functor 0134 //! [3]: http://en.wikipedia.org/wiki/Category_theory 0135 template <typename F> 0136 struct Functor; 0137 }} // end namespace boost::hana 0138 0139 #endif // !BOOST_HANA_FWD_CONCEPT_FUNCTOR_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |