Boost.Hana  1.7.1
Your standard library for metaprogramming
Applicative

Description

The Applicative concept represents Functors with the ability to lift values and combine computations.

A Functor can only take a normal function and map it over a structure containing values to obtain a new structure containing values. Intuitively, an Applicative can also take a value and lift it into the structure. In addition, an Applicative can take a structure containing functions and apply it to a structure containing values to obtain a new structure containing values. By currying the function(s) inside the structure, it is then also possible to apply n-ary functions to n structures containing values.

Note
This documentation does not go into much details about the nature of applicatives. However, the Typeclassopedia is a nice Haskell-oriented resource where such information can be found.

Minimal complete definition

lift and ap satisfying the laws below. An Applicative must also be a Functor.

Laws

Given an Applicative F, the following laws must be satisfied:

  1. Identity
    For all objects xs of tag F(A),
    ap(lift<F>(id), xs) == xs
  2. Composition
    For all objects xs of tag F(A) and functions-in-an-applicative \( fs : F(B \to C) \), \( gs : F(A \to B) \),
    ap(ap(lift<F>(compose), fs, gs), xs) == ap(fs, ap(gs, xs))
    constexpr auto compose
    Return the composition of two functions or more.
    Definition: compose.hpp:52
  3. Homomorphism
    For all objects x of tag A and functions \( f : A \to B \),
    ap(lift<F>(f), lift<F>(x)) == lift<F>(f(x))
  4. Interchange
    For all objects x of tag A and functions-in-an-applicative \( fs : F(A \to B) \),
    ap(fs, lift<F>(x)) == ap(lift<F>(apply(-, x)), fs)
    constexpr auto apply
    Invokes a Callable with the given arguments.
    Definition: apply.hpp:40
    where apply(-, x) denotes the partial application of the apply function from the Functional module to the x argument.

As a consequence of these laws, the model of Functor for F will satisfy the following for all objects xs of tag F(A) and functions \( f : A \to B \):

transform(xs, f) == ap(lift<F>(f), xs)

Refined concept

  1. Functor (free model)
    As a consequence of the laws, any Applicative F can be made a Functor by setting
    transform(xs, f) = ap(lift<F>(f), xs)

Concrete models

hana::lazy, hana::optional, hana::tuple

Structure-preserving functions

An applicative transformation is a function \( t : F(X) \to G(X) \) between two Applicatives F and G, where X can be any tag, and which preserves the operations of an Applicative. In other words, for all objects x of tag X, functions-in-an-applicative \( fs : F(X \to Y) \) and objects xs of tag F(X),

t(lift<F>(x)) == lift<G>(x)
t(ap(fs, xs)) == ap(t(fs), t(xs))

Functions

times boost::hana::A (T_1) \times \cdots \times A(T_n) \to A(U) @f$. const expr auto ap
 Lifted application. More...
 

Variables

template<typename A >
constexpr auto boost::hana::lift
 Lift a value into an Applicative structure. More...
 

Function Documentation

◆ A()

times boost::hana::A ( T_1  ) const

#include <boost/hana/fwd/ap.hpp>

Lifted application.

Specifically, ap applies a structure containing functions to a structure containing values, and returns a new structure containing values. The exact way in which the functions are applied to the values depends on the Applicative.

ap can be called with two arguments or more; the functions in the f structure are curried and then applied to the values in each x... structure using the binary form of ap. Note that this requires the number of x... must match the arity of the functions in the f structure. In other words, ap(f, x1, ..., xN) is equivalent to

((curry(f) ap x1) ap x2) ... ap xN
constexpr auto curry
Curry a function up to the given number of arguments.
Definition: curry.hpp:88

where x ap y is just ap(x, y) written in infix notation to emphasize the left associativity.

Signature

Given an Applicative A, the signature is

Parameters
fA structure containing function(s).
x...Structure(s) containing value(s) and on which f is applied. The number of structures must match the arity of the functions in the f structure.

Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <functional>
namespace hana = boost::hana;
int main() {
// with tuples
static_assert(
hana::ap(hana::make_tuple(std::plus<>{}), hana::make_tuple(1, 2),
hana::make_tuple(3, 4, 5))
==
hana::make_tuple(
1 + 3, 1 + 4, 1 + 5,
2 + 3, 2 + 4, 2 + 5
)
, "");
// with optional values
BOOST_HANA_CONSTEXPR_LAMBDA auto multiply = [](auto a, auto b, auto c) {
return a * b * c;
};
hana::ap(hana::just(multiply), hana::just(1),
hana::just(2),
hana::just(3))
==
hana::just(1 * 2 * 3)
);
hana::ap(hana::just(multiply), hana::just(1),
hana::nothing,
hana::just(3))
==
hana::nothing
);
}
Defines boost::hana::ap.
Defines macros to perform different kinds of assertions.
Defines configuration macros used throughout the library.
Defines boost::hana::equal.
#define BOOST_HANA_CONSTANT_CHECK(...)
Equivalent to BOOST_HANA_CONSTANT_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTI...
Definition: assert.hpp:239
#define BOOST_HANA_CONSTEXPR_CHECK(...)
Equivalent to BOOST_HANA_CONSTEXPR_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERT...
Definition: assert.hpp:300
Namespace containing everything in the library.
Definition: accessors.hpp:20
Defines boost::hana::optional.
Defines boost::hana::tuple.
Todo:
Consider giving access to all the arguments to the tag-dispatched implementation for performance purposes.

Variable Documentation

◆ lift

template<typename A >
constexpr auto boost::hana::lift
constexpr

#include <boost/hana/fwd/lift.hpp>

Initial value:
= [](auto&& x) {
return tag-dispatched;
}

Lift a value into an Applicative structure.

lift<A> takes a normal value and embeds it into a structure whose shape is represented by the A Applicative. Note that the value may be a function, in which case the created structure may be applied to another Applicative structure containing values.

Signature

Given an Applicative A, the signature is \( \mathtt{lift}_A : T \to A(T) \).

Template Parameters
AA tag representing the Applicative into which the value is lifted.
Parameters
xThe value to lift into the applicative.

Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::lift<hana::tuple_tag>('x') == hana::make_tuple('x'), "");
static_assert(hana::lift<hana::optional_tag>('x') == hana::just('x'), "");
int main() { }
Defines boost::hana::lift.