#![doc(include = "../../doc/references.md")]
use crate::helpers::*;
pub trait Magma: Sized + PartialEq {
fn op(&self, other: &Self) -> Self;
}
pub trait MagmaLaws: Magma {
fn closure(&self, _x: &Self) -> bool {
true
}
}
impl<M: Magma> MagmaLaws for M {}
impl Magma for () {
fn op(&self, _: &Self) -> Self {}
}
impl<A: Magma> Magma for (A,) {
fn op(&self, other: &Self) -> Self {
(self.0.op(&other.0), )
}
}
impl<A: Magma, B: Magma> Magma for (A, B) {
fn op(&self, other: &Self) -> Self {
(self.0.op(&other.0), self.1.op(&other.1))
}
}
impl<A: Magma, B: Magma, C: Magma> Magma for (A, B, C) {
fn op(&self, other: &Self) -> Self {
(self.0.op(&other.0), self.1.op(&other.1), self.2.op(&other.2))
}
}
macro_rules! array_magma {
($size:expr) => {
impl<T: Copy + Magma> Magma for [T; $size] {
fn op(&self, other: &Self) -> Self {
self.map_with(other, &|x, y| x.op(y))
}
}
};
($size:expr, $($others:expr),+) => {
array_magma! {$size}
array_magma! {$($others),+}
};
}
array_magma! {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
}