Boost.Hana: Ring

| Boost.Hana 1.5.0 Your standard library for metaprogramming |

Variables
Ring
Concepts

## Description

The `Ring` concept represents `Group`s that also form a `Monoid` under a second binary operation that distributes over the first.

A Ring is an algebraic structure built on top of a `Group` which requires a monoidal structure with respect to a second binary operation. This second binary operation must distribute over the first one. Specifically, a `Ring` is a triple `(S, +, *)` such that `(S, +)` is a `Group`, `(S, *)` is a `Monoid` and `*` distributes over `+`, i.e.

x * (y + z) == (x * y) + (x * z)

The second binary operation is often written `*` with its identity written `1`, in reference to the `Ring` of integers under multiplication. The method names used here refer to this exact ring.

## Minimal complete definintion

`one` and `mult` satisfying the laws

## Laws

For all objects `x`, `y`, `z` of a `Ring` `R`, the following laws must be satisfied:

mult(x, mult(y, z)) == mult(mult(x, y), z) // associativity
mult(x, one<R>()) == x // right identity
mult(one<R>(), x) == x // left identity
mult(x, plus(y, z)) == plus(mult(x, y), mult(x, z)) // distributivity

## Refined concepts

`Monoid`, `Group`

## 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 `Ring` is automatically defined by using the provided `Group` model and setting

mult(x, y) = (x * y)
one<T>() = static_cast<T>(1)

Note
  The rationale for not providing a Ring model for `bool` is the same as for not providing Monoid and Group models.

## Structure-preserving functions

Let `A` and `B` be two `Ring`s. A function `f : A -> B` is said to be a Ring morphism if it preserves the ring 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(mult(x, y)) == mult(f(x), f(y))
f(one<A>()) == one<B>()

Because of the `Ring` structure, it is easy to prove that the following will then also be satisfied:

f(zero<A>()) == zero<B>()
f(negate(x)) == negate(f(x))

which is to say that `f` will then also be a `Group` morphism. Functions with these properties interact nicely with `Ring`s, which is why they are given such a special treatment.

## Variables
constexpr auto | boost::hana::mult
| Associative operation of a `Ring`. More...
template<typename R >
constexpr auto | boost::hana::one
| Identity of the `Ring` multiplication. More...
constexpr auto | boost::hana::power
| Elevate a ring element to its `n`th power.Specifically, `power(x, n)`, is equivalent to multiplying `x` with itself `n` times using the Ring's multiplication. If the power is equal to `zero`, the Ring's identity (`one`) is returned. More...

## Variable Documentation

constexpr auto boost::hana::mult

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

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

Associative operation of a `Ring`.

Parameters

  x,y | Two `Ring` elements to combine with the `Ring` binary operation.

## Cross-type version of the method

The `mult` method is "overloaded" to handle distinct data types with certain properties. Specifically, `mult` 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 `Ring`s when taken individually
3. `to<C> : A -> B` and `to<C> : B -> C` are `Ring`-embeddings, as determined by the `is_embedding` metafunction.

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

mult(x, y) = mult(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/mult.hpp>
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::mult(hana::int_c<3>, hana::int_c<5>) == hana::int_c<15>);
static_assert(hana::mult(4, 2) == 8, "");
int main() { }
template<typename R >

constexpr auto boost::hana::one

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

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

Identity of the `Ring` multiplication.

Template Parameters

  R | The tag (must be a model of `Ring`) 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/one.hpp>
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::one<hana::integral_constant_tag<int>>() == hana::int_c<1>);
static_assert(hana::one<long>() == 1l, "");
int main() { }

constexpr auto boost::hana::power

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

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

Elevate a ring element to its `n`th power.Specifically, `power(x, n)`, is equivalent to multiplying `x` with itself `n` times using the Ring's multiplication. If the power is equal to `zero`, the Ring's identity (`one`) is returned.

Parameters

  x | A `Ring` element that is elevated to its `n`th power.
  n | A non-negative `IntegralConstant` representing the power to which `x` is elevated.

Note
  Only the tag of `x` is used for tag-dispatching.

## 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/power.hpp>
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::power(hana::int_c<3>, hana::int_c<2>) == hana::int_c<3 * 3>);
static_assert(hana::power(2, hana::int_c<4>) == 16, "");
int main() { }