Boost.Hana  1.0.0
Your standard library for metaprogramming


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:

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


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


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.


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.

x,yTwo 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))


// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file or copy at
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
MThe tag (a Monoid) of the returned identity.


// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file or copy at
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() { }