Back to home page

EIC code displayed by LXR

 
 

    


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