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
use super::operator::{Operator, Addition, Multiplication};
use super::semigroup::{Semigroup, SemigroupAdd, SemigroupMul};
use super::identity::Identity;
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);