Boost.Hana: MonadPlus

| Boost.Hana 1.7.1 Your standard library for metaprogramming |

Variables
MonadPlus
Concepts

## Description

The `MonadPlus` concept represents Monads with a monoidal structure.

Intuitively, whereas a Monad can be seen as some kind of container or context, a MonadPlus can be seen as a container or a context that can be concatenated with other containers or contexts. There must also be an identity element for this combining operation. For example, a tuple is a MonadPlus, because tuples can be concatenated and the empty tuple would act as an identity for concatenation. How is this different from a Monad which is also a Monoid? The answer is that the monoidal structure on a MonadPlus must not depend of the contents of the structure; it must not require the contents to be a Monoid in order to work.

While sequences are not the only possible model for MonadPlus, the method names used here refer to the MonadPlus of sequences under concatenation. Several useful functions generalizing operations on sequences are included with this concept, like `append`, `prepend` and `filter`.

Note
  This documentation does not go into much details about the nature of the MonadPlus concept. However, there is a nice Haskell-oriented WikiBook going into further details.

## Minimal complete definition

`concat` and `empty`

## Laws

First, a MonadPlus is required to have a monoidal structure. Hence, it is no surprise that for any MonadPlus `M`, we require `M(T)` to be a valid monoid. However, we do not enforce that `M(T)` actually models the Monoid concept provided by Hana. Further, for all objects `a, b, c` of data type `M(T)`,

// identity
concat(empty<M(T)>(), a) == a
concat(a, empty<M(T)>()) == a
// associativity
concat(a, concat(b, c)) == concat(concat(a, b), c)
boost::hana::concat
constexpr auto concat
Combine two monadic structures together.
Definition: concat.hpp:47
boost::hana::empty
constexpr auto empty
Identity of the monadic combination concat.
Definition: empty.hpp:36

Secondly, a MonadPlus is also required to obey the following laws, which represent the fact that `empty<M(T)>()` must be some kind of absorbing element for the `chain` operation. For all objects `a` of data type `M(T)` and functions \( f : T \to M(U) \),

chain(empty<M(T)>(), f) == empty<M(U)>()
chain(a, always(empty<M(T)>())) == empty<M(U)>()
boost::hana::always
constexpr auto always
Return a constant function returning x regardless of the argument(s) it is invoked with.
Definition: always.hpp:37

## Refined concepts

`Functor`, `Applicative` and `Monad`

## Concrete models

`hana::optional`, `hana::tuple`

## Variables
constexpr auto | boost::hana::append
| Append an element to a monadic structure. More...
constexpr auto | boost::hana::concat
| Combine two monadic structures together. More...
constexpr auto | boost::hana::cycle
| Combine a monadic structure with itself `n` times. More...
template<typename M >
constexpr auto | boost::hana::empty
| Identity of the monadic combination `concat`. More...
constexpr auto | boost::hana::filter
| Filter a monadic structure using a custom predicate. More...
constexpr auto | boost::hana::prefix
| Inserts a value before each element of a monadic structure. More...
constexpr auto | boost::hana::prepend
| Prepend an element to a monadic structure. More...
| boost::hana::mathrm
| Remove all the elements of a monadic structure that are equal to some value. More...
template<typename M >
constexpr auto | boost::hana::replicate
| Create a monadic structure by combining a lifted value with itself `n` times. More...
constexpr auto | boost::hana::suffix
| Inserts a value after each element of a monadic structure. More...

## Variable Documentation

## ◆ append

constexpr auto boost::hana::append
| constexpr

`#include <boost/hana/fwd/append.hpp>`

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

Append an element to a monadic structure.

Given an element `x` and a monadic structure `xs`, `append` returns a new monadic structure which is the result of lifting `x` into the monadic structure and then combining that (to the right) with `xs`. In other words,

append(xs, x) == concat(xs, lift<Xs>(x))
boost::hana::append
constexpr auto append
Append an element to a monadic structure.
Definition: append.hpp:52

where `Xs` is the tag of `xs`. For sequences, this has the intuitive behavior of simply appending an element to the end of the sequence, hence the name.

> #### Rationale for not calling this `push_back` See the rationale for using `prepend` instead of `push_front`.

## Signature

Given a MonadPlus `M`, the signature is \( \mathtt{append} : M(T) \times T \to M(T) \).

Parameters

  xs | A monadic structure that will be combined to the left of the element.
  x | An element to combine to the right of the monadic 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 <boost/hana/append.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
static_assert(hana::append(hana::make_tuple(), 1) == hana::make_tuple(1), "");
static_assert(hana::append(hana::make_tuple(1, '2'), 3.3) == hana::make_tuple(1, '2', 3.3), "");
static_assert(hana::append(hana::append(hana::append(hana::make_tuple(), 1), '2'), 3.3) == hana::make_tuple(1, '2', 3.3), "");
int main() { }
append.hpp
Defines boost::hana::append.
equal.hpp
Defines boost::hana::equal.
boost::hana
Namespace containing everything in the library.
Definition: accessors.hpp:20
tuple.hpp
Defines boost::hana::tuple.

## ◆ concat

constexpr auto boost::hana::concat
| constexpr

`#include <boost/hana/fwd/concat.hpp>`

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

Combine two monadic structures together.

Given two monadic structures, `concat` combines them together and returns a new monadic structure. The exact definition of `concat` will depend on the exact model of MonadPlus at hand, but for sequences it corresponds intuitively to simple concatenation.

Also note that combination is not required to be commutative. In other words, there is no requirement that

concat(xs, ys) == concat(ys, xs)

and indeed it does not hold in general.

## Signature

Given a `MonadPlus` `M`, the signature of `concat` is \( \mathtt{concat} : M(T) \times M(T) \to M(T) \).

Parameters

  xs,ys | Two monadic structures to combine together.

## 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 <boost/hana/concat.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
static_assert(
hana::concat(hana::make_tuple(1, '2'), hana::make_tuple(3.3, 4_c))
==
hana::make_tuple(1, '2', 3.3, 4_c)
, "");
int main() { }
concat.hpp
Defines boost::hana::concat.
integral_constant.hpp
Defines boost::hana::integral_constant.

## ◆ cycle

constexpr auto boost::hana::cycle
| constexpr

`#include <boost/hana/fwd/cycle.hpp>`

Initial value:
= [](auto&& xs, auto const& n) {
return tag-dispatched;
}

Combine a monadic structure with itself `n` times.

Given a monadic structure `xs` and a non-negative number `n`, `cycle` returns a new monadic structure which is the result of combining `xs` with itself `n` times using the `concat` operation. In other words,

cycle(xs, n) == concat(xs, concat(xs, ... concat(xs, xs)))
// ^^^^^ n times total
boost::hana::cycle
constexpr auto cycle
Combine a monadic structure with itself n times.
Definition: cycle.hpp:60

Also note that since `concat` is required to be associative, we could also have written

cycle(xs, n) == concat(concat(... concat(xs, xs), xs), xs)
// ^^^^^ n times total

If `n` is zero, then the identity of `concat`, `empty`, is returned. In the case of sequences, this boils down to returning a sequence containing `n` copies of itself; for other models it might differ.

## Signature

Given an `IntegralConstant` `C` and a `MonadPlus` `M`, the signature is \( \mathrm{cycle} : M(T) \times C \to M(T) \).

Parameters

  xs | A monadic structure to combine with itself a certain number of times.
  n | A non-negative `IntegralConstant` representing the number of times to combine the monadic structure with itself. If `n` is zero, `cycle` returns `empty`.

## 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 <boost/hana/cycle.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
static_assert(hana::cycle(hana::make_tuple('x', 'y'), hana::size_c<2>) == hana::make_tuple('x', 'y', 'x', 'y'), "");
int main() { }
cycle.hpp
Defines boost::hana::cycle.

## ◆ empty

template<typename M >

constexpr auto boost::hana::empty
| constexpr

`#include <boost/hana/fwd/empty.hpp>`

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

Identity of the monadic combination `concat`.

## Signature

Given a MonadPlus `M`, the signature is \( \mathtt{empty}_M : \emptyset \to M(T) \).

Template Parameters

  M | The tag of the monadic structure to return. This must be a model of the MonadPlus concept.

## 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 <boost/hana/assert.hpp>
#include <boost/hana/empty.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::empty<hana::tuple_tag>() == hana::make_tuple());
BOOST_HANA_CONSTANT_CHECK(hana::empty<hana::optional_tag>() == hana::nothing);
int main() { }
assert.hpp
Defines macros to perform different kinds of assertions.
empty.hpp
Defines boost::hana::empty.
BOOST_HANA_CONSTANT_CHECK
#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
optional.hpp
Defines boost::hana::optional.

## ◆ filter

constexpr auto boost::hana::filter
| constexpr

`#include <boost/hana/fwd/filter.hpp>`

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

Filter a monadic structure using a custom predicate.

Given a monadic structure and a predicate, `filter` returns a new monadic structure containing only those elements that satisfy the predicate. This is a generalization of the usual `filter` function for sequences; it works for any MonadPlus. Intuitively, `filter` is somewhat equivalent to:

filter(xs, pred) == flatten(transform(xs, [](auto x) {
return pred(x) ? lift<Xs>(x) : empty<Xs>();
})
boost::hana::filter
constexpr auto filter
Filter a monadic structure using a custom predicate.
Definition: filter.hpp:65

In other words, we basically turn a monadic structure containing `[x1, ..., xn]` into a monadic structure containing

[
pred(x1) ? [x1] : [],
pred(x2) ? [x2] : [],
...
pred(xn) ? [xn] : []
]

and we then `flatten` that.

## Signature

Given a `MonadPlus` `M` and an `IntegralConstant` `Bool` holding a value of type `bool`, the signature is \( \mathtt{filter} : M(T) \times (T \to \mathtt{Bool}) \to M(T) \).

Parameters

  xs | The monadic structure to filter.
  pred | A function called as `pred(x)` for each element `x` in the monadic structure and returning whether that element should be kept in the resulting structure. In the current version of the library, the predicate has to return an `IntegralConstant` holding a value convertible to a `bool`.

## 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 <boost/hana/assert.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/ext/std/integral_constant.hpp>
#include <boost/hana/filter.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/type.hpp>
#include <type_traits>
namespace hana = boost::hana;
// First take the type of an object, and then tell whether it's integral
constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::typeid_);
static_assert(hana::filter(hana::make_tuple(1, 2.0, 3, 4.0), is_integral) == hana::make_tuple(1, 3), "");
static_assert(hana::filter(hana::just(3), is_integral) == hana::just(3), "");
BOOST_HANA_CONSTANT_CHECK(hana::filter(hana::just(3.0), is_integral) == hana::nothing);
int main() { }
compose.hpp
Defines boost::hana::compose.
integral_constant.hpp
Adapts std::integral_constant for use with Hana.
filter.hpp
Defines boost::hana::filter.
boost::hana::compose
constexpr auto compose
Return the composition of two functions or more.
Definition: compose.hpp:52
type.hpp
Defines boost::hana::type and related utilities.

## ◆ prefix

constexpr auto boost::hana::prefix
| constexpr

`#include <boost/hana/fwd/prefix.hpp>`

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

Inserts a value before each element of a monadic structure.

Given a monadic structure `xs` and a value `z` called the prefix, `prefix` returns a new monadic structure. `prefix` satisfies

prefix(xs, z) == flatten(transform(xs, [](auto x) {
return concat(lift<M>(z), lift<M>(x));
}))
boost::hana::prefix
constexpr auto prefix
Inserts a value before each element of a monadic structure.
Definition: prefix.hpp:56

For sequences, this simply corresponds to inserting the prefix before each element of the sequence. For example, given a sequence `[x1, ..., xn]`, `prefix` will return

[z, x1, z, x2, ..., z, xn]

As explained above, this can be generalized to other MonadPlus models, with various levels of interest.

## Signature

Given a MonadPlus `M`, the signature is \( \mathrm{prefix} : M(T) \times T \to M(T) \).

Parameters

  xs | A monadic structure.
  pref | A value (the prefix) to insert before each element of a monadic 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 <boost/hana/assert.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/prefix.hpp>
#include <boost/hana/tuple.hpp>
#include <string>
namespace hana = boost::hana;
using namespace std::literals;
int main() {
BOOST_HANA_RUNTIME_CHECK(
hana::prefix(hana::make_tuple("dog"s, "car"s, "house"s), "my"s)
==
hana::make_tuple("my", "dog", "my", "car", "my", "house")
);
}
BOOST_HANA_RUNTIME_CHECK
#define BOOST_HANA_RUNTIME_CHECK(...)
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIO...
Definition: assert.hpp:209
prefix.hpp
Defines boost::hana::prefix.

## ◆ prepend

constexpr auto boost::hana::prepend
| constexpr

`#include <boost/hana/fwd/prepend.hpp>`

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

Prepend an element to a monadic structure.

Given a monadic structure `xs` and an element `x`, `prepend` returns a new monadic structure which is the result of lifting `x` into the monadic structure and then combining that (to the left) with `xs`. In other words,

prepend(xs, x) == concat(lift<Xs>(x), xs)
boost::hana::prepend
constexpr auto prepend
Prepend an element to a monadic structure.
Definition: prepend.hpp:57

For sequences, this has the intuitive behavior of simply prepending an element to the beginning of the sequence, hence the name.

> #### Rationale for not calling this `push_front` While `push_front` is the de-facto name used in the standard library, it also strongly suggests mutation of the underlying sequence, which is not the case here. The author also finds that `push_front` suggests too strongly the sole interpretation of putting an element to the front of a sequence, whereas `prepend` is slightly more nuanced and bears its name better for e.g. `hana::optional`.

## Signature

Given a MonadPlus `M`, the signature is \( \mathtt{prepend} : M(T) \times T \to M(T) \).

Parameters

  xs | A monadic structure that will be combined to the right of the element.
  x | An element to combine to the left of the monadic 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 <boost/hana/equal.hpp>
#include <boost/hana/prepend.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
static_assert(hana::prepend(hana::make_tuple(), 1) == hana::make_tuple(1), "");
static_assert(hana::prepend(hana::make_tuple('2', 3.3), 1) == hana::make_tuple(1, '2', 3.3), "");
int main() { }
prepend.hpp
Defines boost::hana::prepend.

## ◆ mathrm

boost::hana::mathrm

`#include <boost/hana/fwd/remove.hpp>`

Initial value:
{remove} : M(T) \times T \to M(T)
\f$
constexpr auto remove = [](auto&& xs, auto&& value) {
return tag-dispatched;
}
boost::hana::value
constexpr auto value
Return the compile-time value associated to a constant.
Definition: value.hpp:54
boost::hana::to
constexpr auto to
Converts an object from one data type to another.
Definition: to.hpp:97

Remove all the elements of a monadic structure that are equal to some value.

Remove all the elements of a monadic structure that satisfy some predicate.

Given a monadic structure `xs` and a `value`, `remove` returns a new monadic structure equal to `xs` without all its elements that are equal to the given `value`. `remove` is equivalent to `remove_if` with the `equal.to(value)` predicate, i.e.

remove(xs, value) == remove_if(xs, equal.to(value))
boost::hana::equal
constexpr auto equal
Returns a Logical representing whether x is equal to y.
Definition: equal.hpp:64

## Signature

Given a MonadPlus `M` and a value of type `T`, the signature is

Given a monadic structure `xs` and a unary predicate, `remove_if` returns a new monadic structure equal to `xs` without all its elements that satisfy the predicate. This is equivalent to `filter` with a negated predicate, i.e.

remove_if(xs, predicate) == filter(xs, negated predicated)

## Signature

Given a MonadPlus `M` and a predicate of type \( T \to Bool \) for some compile-time Logical `Bool`, the signature is

## ◆ replicate

template<typename M >

constexpr auto boost::hana::replicate
| constexpr

`#include <boost/hana/fwd/replicate.hpp>`

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

Create a monadic structure by combining a lifted value with itself `n` times.

Given a value `x`, a non-negative `IntegralConstant` `n` and the tag of a monadic structure `M`, `replicate` creates a new monadic structure which is the result of combining `x` with itself `n` times inside the monadic structure. In other words, `replicate` simply `lift`s `x` into the monadic structure, and then combines that with itself `n` times:

replicate<M>(x, n) == cycle(lift<M>(x), n)

If `n` is zero, then the identity of the `concat` operation is returned. In the case of sequences, this corresponds to creating a new sequence holding `n` copies of `x`.

## Signature

Given an `IntegralConstant` `C` and MonadPlus `M`, the signature is \( \mathtt{replicate}_M : T \times C \to M(T) \).

Template Parameters

  M | The tag of the returned monadic structure. It must be a model of the MonadPlus concept.

Parameters

  x | The value to lift into a monadic structure and then combine with itself.
  n | A non-negative `IntegralConstant` representing the number of times to combine `lift<M>(x)` with itself. If `n == 0`, `replicate` returns `empty<M>()`.

## 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 <boost/hana/equal.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/replicate.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
static_assert(hana::replicate<hana::tuple_tag>('x', hana::size_c<2>) == hana::make_tuple('x', 'x'), "");
// Of course, there can't be more than one element in an `optional`.
static_assert(hana::replicate<hana::optional_tag>('x', hana::size_c<2>) == hana::just('x'), "");
int main() { }
replicate.hpp
Defines boost::hana::replicate.

## ◆ suffix

constexpr auto boost::hana::suffix
| constexpr

`#include <boost/hana/fwd/suffix.hpp>`

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

Inserts a value after each element of a monadic structure.

Given a monadic structure `xs` and a value `z` (called the suffix), `suffix` returns a new monadic structure such that

suffix(xs, z) == flatten(transform(xs, [](auto x) {
return concat(lift<M>(x), lift<M>(z));
}))
boost::hana::suffix
constexpr auto suffix
Inserts a value after each element of a monadic structure.
Definition: suffix.hpp:56

For sequences, this simply corresponds to inserting the suffix after each element of the sequence. For example, given a sequence `[x1, ..., xn]`, `suffix` will return

[x1, z, x2, z, ..., xn, z]

As explained above, this can be generalized to other MonadPlus models, with various levels of interest.

## Signature

Given a MonadPlus `M`, the signature is \( \mathtt{suffix} : M(T) \times T \to M(T) \).

Parameters

  xs | A monadic structure.
  sfx | A value (the suffix) to insert after each element of a monadic 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 <boost/hana/equal.hpp>
#include <boost/hana/suffix.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
static_assert(
hana::suffix(hana::make_tuple(1, 2, 3, 4), 0) == hana::make_tuple(1, 0, 2, 0, 3, 0, 4, 0)
, "");
int main() { }
suffix.hpp
Defines boost::hana::suffix.