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::Applicative`.
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_APPLICATIVE_HPP
0011 #define BOOST_HANA_FWD_CONCEPT_APPLICATIVE_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 
0015 
0016 namespace boost { namespace hana {
0017     //! @ingroup group-concepts
0018     //! @defgroup group-Applicative Applicative
0019     //! The `Applicative` concept represents `Functor`s with the ability
0020     //! to lift values and combine computations.
0021     //!
0022     //! A `Functor` can only take a normal function and map it over a
0023     //! structure containing values to obtain a new structure containing
0024     //! values. Intuitively, an `Applicative` can also take a value and
0025     //! lift it into the structure. In addition, an `Applicative` can take
0026     //! a structure containing functions and apply it to a structure
0027     //! containing values to obtain a new structure containing values.
0028     //! By currying the function(s) inside the structure, it is then
0029     //! also possible to apply n-ary functions to n structures containing
0030     //! values.
0031     //!
0032     //! @note
0033     //! This documentation does not go into much details about the nature
0034     //! of applicatives. However, the [Typeclassopedia][1] is a nice
0035     //! Haskell-oriented resource where such information can be found.
0036     //!
0037     //!
0038     //! Minimal complete definition
0039     //! ---------------------------
0040     //! `lift` and `ap` satisfying the laws below. An `Applicative` must
0041     //! also be a `Functor`.
0042     //!
0043     //!
0044     //! Laws
0045     //! ----
0046     //! Given an `Applicative` `F`, the following laws must be satisfied:
0047     //! 1. Identity\n
0048     //! For all objects `xs` of tag `F(A)`,
0049     //! @code
0050     //!     ap(lift<F>(id), xs) == xs
0051     //! @endcode
0052     //!
0053     //! 2. Composition\n
0054     //! For all objects `xs` of tag `F(A)` and functions-in-an-applicative
0055     //! @f$ fs : F(B \to C) @f$,
0056     //! @f$ gs : F(A \to B) @f$,
0057     //! @code
0058     //!     ap(ap(lift<F>(compose), fs, gs), xs) == ap(fs, ap(gs, xs))
0059     //! @endcode
0060     //!
0061     //! 3. Homomorphism\n
0062     //! For all objects `x` of tag `A` and functions @f$ f : A \to B @f$,
0063     //! @code
0064     //!     ap(lift<F>(f), lift<F>(x)) == lift<F>(f(x))
0065     //! @endcode
0066     //!
0067     //! 4. Interchange\n
0068     //! For all objects `x` of tag `A` and functions-in-an-applicative
0069     //! @f$ fs : F(A \to B) @f$,
0070     //! @code
0071     //!     ap(fs, lift<F>(x)) == ap(lift<F>(apply(-, x)), fs)
0072     //! @endcode
0073     //! where `apply(-, x)` denotes the partial application of the `apply`
0074     //! function from the @ref group-functional module to the `x` argument.
0075     //!
0076     //! As a consequence of these laws, the model of `Functor` for `F` will
0077     //! satisfy the following for all objects `xs` of tag `F(A)` and functions
0078     //! @f$ f : A \to B @f$:
0079     //! @code
0080     //!     transform(xs, f) == ap(lift<F>(f), xs)
0081     //! @endcode
0082     //!
0083     //!
0084     //! Refined concept
0085     //! ---------------
0086     //! 1. `Functor` (free model)\n
0087     //! As a consequence of the laws, any `Applicative F` can be made a
0088     //! `Functor` by setting
0089     //! @code
0090     //!     transform(xs, f) = ap(lift<F>(f), xs)
0091     //! @endcode
0092     //!
0093     //!
0094     //! Concrete models
0095     //! ---------------
0096     //! `hana::lazy`, `hana::optional`, `hana::tuple`
0097     //!
0098     //!
0099     //! @anchor applicative-transformation
0100     //! Structure-preserving functions
0101     //! ------------------------------
0102     //! An _applicative transformation_ is a function @f$ t : F(X) \to G(X) @f$
0103     //! between two Applicatives `F` and `G`, where `X` can be any tag, and
0104     //! which preserves the operations of an Applicative. In other words, for
0105     //! all objects `x` of tag `X`, functions-in-an-applicative
0106     //! @f$ fs : F(X \to Y) @f$ and objects `xs` of tag `F(X)`,
0107     //! @code
0108     //!     t(lift<F>(x)) == lift<G>(x)
0109     //!     t(ap(fs, xs)) == ap(t(fs), t(xs))
0110     //! @endcode
0111     //!
0112     //! [1]: https://wiki.haskell.org/Typeclassopedia#Applicative
0113     template <typename A>
0114     struct Applicative;
0115 }} // end namespace boost::hana
0116 
0117 #endif // !BOOST_HANA_FWD_CONCEPT_APPLICATIVE_HPP