#![doc(include = "../../doc/references.md")]
use crate::magma::*;
pub trait Semigroup: Magma {}
pub trait SemigroupLaws: Semigroup {
fn associativity(&self, x: &Self, y: &Self) -> bool {
self.op(&x.op(y)) == self.op(x).op(y)
}
}
impl<S: Semigroup> SemigroupLaws for S {}
impl Semigroup for () {}
impl<A: Semigroup> Semigroup for (A,) {}
impl<A: Semigroup, B: Semigroup> Semigroup for (A, B) {}
impl<A: Semigroup, B: Semigroup, C: Semigroup> Semigroup for (A, B, C) {}
macro_rules! array_semigroup {
($size:expr) => {
impl<T: Copy + Semigroup> Semigroup for [T; $size] {}
};
($size:expr, $($others:expr),+) => {
array_semigroup! {$size}
array_semigroup! {$($others),+}
};
}
array_semigroup! {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
}