 Boost.Hana  1.6.0 Your standard library for metaprogramming Monoid

## Description

The Monoid concept represents data types with an associative binary operation that has an identity.

Specifically, a Monoid is a basic algebraic structure typically used in mathematics to construct more complex algebraic structures like Groups, Rings and so on. They are useful in several contexts, notably to define the properties of numbers in a granular way. At its core, a Monoid is a set S of objects along with a binary operation (let's say +) that is associative and that has an identity in S. There are many examples of Monoids:

• strings with concatenation and the empty string as the identity
• integers with addition and 0 as the identity
• integers with multiplication and 1 as the identity
• many others...

As you can see with the integers, there are some sets that can be viewed as a monoid in more than one way, depending on the choice of the binary operation and identity. The method names used here refer to the monoid of integers under addition; plus is the binary operation and zero is the identity element of that operation.

## Minimal complete definition

plus and zero satisfying the laws

## Laws

For all objects x, y and z of a Monoid M, the following laws must be satisfied:

plus(zero<M>(), x) == x // left zero
plus(x, zero<M>()) == x // right zero
plus(x, plus(y, z)) == plus(plus(x, y), z) // associativity

## Concrete models

hana::integral_constant

## Free model for non-boolean arithmetic data types

A data type T is arithmetic if std::is_arithmetic<T>::value is true. For a non-boolean arithmetic data type T, a model of Monoid is automatically defined by setting

plus(x, y) = (x + y)
zero<T>() = static_cast<T>(0)

#### Rationale for not making bool a Monoid by default

First, it makes no sense whatsoever to define an additive Monoid over the bool type. Also, it could make sense to define a Monoid with logical conjunction or disjunction. However, C++ allows bools to be added, and the method names of this concept really suggest addition. In line with the principle of least surprise, no model is provided by default.

## Structure-preserving functions

Let A and B be two Monoids. A function f : A -> B is said to be a Monoid morphism if it preserves the monoidal structure between A and B. Rigorously, for all objects x, y of data type A,

f(plus(x, y)) == plus(f(x), f(y))
f(zero<A>()) == zero<B>()

Functions with these properties interact nicely with Monoids, which is why they are given such a special treatment.

## Variables

constexpr auto boost::hana::plus
Associative binary operation on a Monoid. More...

template<typename M >
constexpr auto boost::hana::zero
Identity of plus. More...

## ◆ plus

 constexpr auto boost::hana::plus

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

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

Associative binary operation on a Monoid.

Parameters
 x,y Two objects to combine with the Monoid's binary operation.

## Cross-type version of the method

The plus method is "overloaded" to handle distinct data types with certain properties. Specifically, plus is defined for distinct data types A and B such that

1. A and B share a common data type C, as determined by the common metafunction
2. A, B and C are all Monoids when taken individually
3. to<C> : A -> B and to<C> : B -> C are Monoid-embeddings, as determined by the is_embedding metafunction.

The definition of plus for data types satisfying the above properties is obtained by setting

plus(x, y) = plus(to<C>(x), to<C>(y))

## Example

namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::plus(hana::int_c<3>, hana::int_c<5>) == hana::int_c<8>);
static_assert(hana::plus(1, 2) == 3, "");
static_assert(hana::plus(1.5f, 2.4) == 3.9, "");
int main() { }

## ◆ zero

template<typename M >
 constexpr auto boost::hana::zero

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

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

Identity of plus.

Template Parameters
 M The tag (a Monoid) of the returned identity.