Boost.Hana: Monoid

| Boost.Hana 1.4.0 Your standard library for metaprogramming |

Variables
Monoid
Concepts

## 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 `Group`s, `Ring`s 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 `Monoid`s:

- 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 `bool`s 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 `Monoid`s. 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 `Monoid`s, 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...

## Variable Documentation

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 `Monoid`s 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

// 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/integral_constant.hpp>
#include <boost/hana/plus.hpp>
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() { }
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.

## 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/integral_constant.hpp>
#include <boost/hana/zero.hpp>
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::zero<hana::integral_constant_tag<int>>() == hana::int_c<0>);
static_assert(hana::zero<long>() == 0l, "");
int main() { }