1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! Monoid
use super::operator::{Operator, Addition, Multiplication};
use super::semigroup::{Semigroup, SemigroupAdd, SemigroupMul};
use super::identity::Identity;

/// A Monoid is a triple $`(\mathbb{M}, \circ, e)`$, composed by a set $`\mathbb{M}`$ and a binary inner operation $`\circ`$
/// and the element $`e \in \mathbb{M}`$
/// # Definition
///
/// ```math
/// \circ: \mathbb{M} \times \mathbb{M} \rightarrow \mathbb{M} , (x, y) \mapsto x \circ y
/// ```
/// 1. associativity <br>
/// $`\forall x, y, z \in \mathbb{M}`$: $`x \circ (y \circ z) = (x \circ y) \circ z`$
/// 2. $`e`$ neutral element <br>
/// $`\forall x \in \mathbb{M}`$: $`x \circ e = e \circ x = x`$
pub trait Monoid<O: Operator>: Semigroup<O> + Identity<O>
{

}

macro_rules! impl_monoid
(
    ($O:ty; $op: ident; $($T:ty),*) =>
    {
        $(
            impl Monoid<$O> for $T
            {
            }
        )*
    }
);

impl_monoid!(Addition; add; u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
impl_monoid!(Multiplication; mul; u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);

pub trait MonoidAdd: Monoid<Addition> + SemigroupAdd + Zero
{

}

macro_rules! impl_monoidadd
(
    ($($T:ty),*) =>
    {
        $(
            impl MonoidAdd for $T
            {

            }
        )*
    }
);

impl_monoidadd!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);

pub trait MonoidMul: Monoid<Multiplication> + SemigroupMul + One
{

}

macro_rules! impl_monoidmul
(
    ($($T:ty),*) =>
    {
        $(
            impl MonoidMul for $T
            {

            }
        )*
    }
);

impl_monoidmul!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);


pub trait One
{
    fn one() -> Self;
}

macro_rules! impl_one
{
    ($v:expr; $($t:ty),+) =>
    {
    	$(
        impl One for $t
        {
            fn one() -> Self
            {
                return $v;
            }
        }
        )*
    };
}

impl_one!(1; u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
impl_one!(1.0; f32, f64);

pub trait Zero
{
    fn zero() -> Self;
}

macro_rules! impl_zero
{
    ($v:expr; $($t:ty),*) =>
    {
    	$(
        impl Zero for $t
        {
            fn zero() -> Self
            {
                return $v;
            }
        }
        )*
    };
}

impl_zero!(0; u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
impl_zero!(0.0; f32, f64);