cp_library_rs/algebraic_structure/
monoid.rs1use crate::algebraic_structure::operation::{Add, Max, Min, MinMax, Mul, WrappingAdd, Xor, GCD};
8
9use num::Zero;
10use num_traits::{Bounded, One};
11
12pub trait Monoid {
18 type Val: Clone;
20 fn e() -> Self::Val;
22 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val;
24}
25
26impl Monoid for () {
28 type Val = ();
29 fn e() -> Self::Val {}
30 fn op(_: &Self::Val, _: &Self::Val) -> Self::Val {}
31}
32
33impl<T: Ord + Bounded + Clone> Monoid for Min<T> {
34 type Val = T;
35 fn e() -> Self::Val {
36 Self::Val::max_value()
37 }
38 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
39 left.min(right).clone()
40 }
41}
42
43impl<T: Ord + Bounded + Clone> Monoid for Max<T> {
44 type Val = T;
45 fn e() -> Self::Val {
46 Self::Val::min_value()
47 }
48 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
49 left.max(right).clone()
50 }
51}
52
53impl<T: Ord + Bounded + Clone> Monoid for MinMax<T> {
54 type Val = (T, T);
55 fn e() -> Self::Val {
56 (Min::e(), Max::e())
57 }
58 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
59 (Min::op(&left.0, &right.0), Max::op(&left.1, &right.1))
60 }
61}
62
63impl<T: Zero + Clone> Monoid for Add<T> {
64 type Val = T;
65 fn e() -> Self::Val {
66 T::zero()
67 }
68 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
69 left.clone() + right.clone()
70 }
71}
72
73impl Monoid for WrappingAdd {
74 type Val = usize;
75 fn e() -> Self::Val {
76 0
77 }
78 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
79 left.wrapping_add(*right)
80 }
81}
82
83impl<T: One + Clone> Monoid for Mul<T> {
84 type Val = T;
85 fn e() -> Self::Val {
86 T::one()
87 }
88 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
89 left.clone() * right.clone()
90 }
91}
92
93impl Monoid for Xor {
94 type Val = usize;
95 fn e() -> Self::Val {
96 0
97 }
98 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
99 left ^ right
100 }
101}
102
103impl<T> Monoid for GCD<T> {
104 type Val = usize;
105 fn e() -> Self::Val {
106 0
107 }
108 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
109 GCD::gcd(left, right)
110 }
111}