summaryrefslogtreecommitdiff
path: root/boost/hana/fwd/concept/functor.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/hana/fwd/concept/functor.hpp')
-rw-r--r--boost/hana/fwd/concept/functor.hpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/boost/hana/fwd/concept/functor.hpp b/boost/hana/fwd/concept/functor.hpp
new file mode 100644
index 0000000000..6d2ea170f6
--- /dev/null
+++ b/boost/hana/fwd/concept/functor.hpp
@@ -0,0 +1,139 @@
+/*!
+@file
+Forward declares `boost::hana::Functor`.
+
+@copyright Louis Dionne 2013-2016
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_HANA_FWD_CONCEPT_FUNCTOR_HPP
+#define BOOST_HANA_FWD_CONCEPT_FUNCTOR_HPP
+
+#include <boost/hana/config.hpp>
+
+
+BOOST_HANA_NAMESPACE_BEGIN
+ //! @ingroup group-concepts
+ //! @defgroup group-Functor Functor
+ //! The `Functor` concept represents types that can be mapped over.
+ //!
+ //! Intuitively, a [Functor][1] is some kind of box that can hold generic
+ //! data and map a function over this data to create a new, transformed
+ //! box. Because we are only interested in mapping a function over the
+ //! contents of a black box, the only real requirement for being a functor
+ //! is to provide a function which can do the mapping, along with a couple
+ //! of guarantees that the mapping is well-behaved. Those requirements are
+ //! made precise in the laws below. The pattern captured by `Functor` is
+ //! very general, which makes it widely useful. A lot of objects can be
+ //! made `Functor`s in one way or another, the most obvious example being
+ //! sequences with the usual mapping of the function on each element.
+ //! While this documentation will not go into much more details about
+ //! the nature of functors, the [Typeclassopedia][2] is a nice
+ //! Haskell-oriented resource for such information.
+ //!
+ //! Functors are parametric data types which are parameterized over the
+ //! data type of the objects they contain. Like everywhere else in Hana,
+ //! this parametricity is only at the documentation level and it is not
+ //! enforced.
+ //!
+ //! In this library, the mapping function is called `transform` after the
+ //! `std::transform` algorithm, but other programming languages have given
+ //! it different names (usually `map`).
+ //!
+ //! @note
+ //! The word _functor_ comes from functional programming, where the
+ //! concept has been used for a while, notably in the Haskell programming
+ //! language. Haskell people borrowed the term from [category theory][3],
+ //! which, broadly speaking, is a field of mathematics dealing with
+ //! abstract structures and transformations between those structures.
+ //!
+ //!
+ //! Minimal complete definitions
+ //! ----------------------------
+ //! 1. `transform`\n
+ //! When `transform` is specified, `adjust_if` is defined analogously to
+ //! @code
+ //! adjust_if(xs, pred, f) = transform(xs, [](x){
+ //! if pred(x) then f(x) else x
+ //! })
+ //! @endcode
+ //!
+ //! 2. `adjust_if`\n
+ //! When `adjust_if` is specified, `transform` is defined analogously to
+ //! @code
+ //! transform(xs, f) = adjust_if(xs, always(true), f)
+ //! @endcode
+ //!
+ //!
+ //! Laws
+ //! ----
+ //! Let `xs` be a Functor with tag `F(A)`,
+ //! \f$ f : A \to B \f$ and
+ //! \f$ g : B \to C \f$.
+ //! The following laws must be satisfied:
+ //! @code
+ //! transform(xs, id) == xs
+ //! transform(xs, compose(g, f)) == transform(transform(xs, f), g)
+ //! @endcode
+ //! The first line says that mapping the identity function should not do
+ //! anything, which precludes the functor from doing something nasty
+ //! behind the scenes. The second line states that mapping the composition
+ //! of two functions is the same as mapping the first function, and then
+ //! the second on the result. While the usual functor laws are usually
+ //! restricted to the above, this library includes other convenience
+ //! methods and they should satisfy the following equations.
+ //! Let `xs` be a Functor with tag `F(A)`,
+ //! \f$ f : A \to A \f$,
+ //! \f$ \mathrm{pred} : A \to \mathrm{Bool} \f$
+ //! for some `Logical` `Bool`, and `oldval`, `newval`, `value` objects
+ //! of tag `A`. Then,
+ //! @code
+ //! adjust(xs, value, f) == adjust_if(xs, equal.to(value), f)
+ //! adjust_if(xs, pred, f) == transform(xs, [](x){
+ //! if pred(x) then f(x) else x
+ //! })
+ //! replace_if(xs, pred, value) == adjust_if(xs, pred, always(value))
+ //! replace(xs, oldval, newval) == replace_if(xs, equal.to(oldval), newval)
+ //! fill(xs, value) == replace_if(xs, always(true), value)
+ //! @endcode
+ //! The default definition of the methods will satisfy these equations.
+ //!
+ //!
+ //! Concrete models
+ //! ---------------
+ //! `hana::lazy`, `hana::optional`, `hana::tuple`
+ //!
+ //!
+ //! Structure-preserving functions for Functors
+ //! -------------------------------------------
+ //! A mapping between two functors which also preserves the functor
+ //! laws is called a natural transformation (the term comes from
+ //! category theory). A natural transformation is a function `f`
+ //! from a functor `F` to a functor `G` such that for every other
+ //! function `g` with an appropriate signature and for every object
+ //! `xs` of tag `F(X)`,
+ //! @code
+ //! f(transform(xs, g)) == transform(f(xs), g)
+ //! @endcode
+ //!
+ //! There are several examples of such transformations, like `to<tuple_tag>`
+ //! when applied to an optional value. Indeed, for any function `g` and
+ //! `hana::optional` `opt`,
+ //! @code
+ //! to<tuple_tag>(transform(opt, g)) == transform(to<tuple_tag>(opt), g)
+ //! @endcode
+ //!
+ //! Of course, natural transformations are not limited to the `to<...>`
+ //! functions. However, note that any conversion function between Functors
+ //! should be natural for the behavior of the conversion to be intuitive.
+ //!
+ //!
+ //! [1]: http://en.wikipedia.org/wiki/Functor
+ //! [2]: https://wiki.haskell.org/Typeclassopedia#Functor
+ //! [3]: http://en.wikipedia.org/wiki/Category_theory
+ template <typename F>
+ struct Functor;
+BOOST_HANA_NAMESPACE_END
+
+#endif // !BOOST_HANA_FWD_CONCEPT_FUNCTOR_HPP