pub trait Closure<T> {
fn apply(lhs: T, rhs: T) -> T;
}
pub unsafe trait Associativity<T>: Closure<T> {}
pub unsafe trait Devisiablility<T>: Closure<T> {
fn devide(lhs: T, rhs: T) -> T;
}
pub unsafe trait Identity<T>: Closure<T> {
fn identity() -> T;
}
pub unsafe trait Invertibility<T>: Closure<T> {
fn inverse(value: T) -> T;
}
unsafe impl<T, Op> Invertibility<T> for Op
where Op: Devisiablility<T> + Identity<T>
{
fn inverse(value: T) -> T {
Self::devide(Self::identity(), value)
}
}
pub unsafe trait Commutativity<T>: Closure<T> {}
pub trait Magma
where Self: Sized
{
type Operation: Closure<Self>;
fn apply(lhs: Self, rhs: Self) -> Self {
Self::Operation::apply(lhs, rhs)
}
}
pub trait Semigroup: Magma {}
impl<T, Op> Semigroup for T
where T: Magma<Operation = Op>,
Op: Associativity<T>
{
}
pub trait Monoid: Magma {
fn mempty() -> Self;
fn mappend(self, rhs: Self) -> Self;
}
impl<T, Op> Monoid for T
where T: Magma<Operation = Op>,
Op: Associativity<T> + Identity<T>
{
fn mempty() -> Self {
Op::identity()
}
fn mappend(self, rhs: Self) -> Self {
Op::apply(self, rhs)
}
}
pub trait Quasigroup: Magma {}
impl<T, Op> Quasigroup for T
where T: Magma<Operation = Op>,
Op: Devisiablility<T>
{
}
pub trait Loop: Magma {}
impl<T, Op> Loop for T
where T: Magma<Operation = Op>,
Op: Devisiablility<T> + Identity<T>
{
}
pub trait Group: Magma {}
impl<T, Op> Group for T
where T: Magma<Operation = Op>,
Op: Devisiablility<T> + Associativity<T> + Identity<T>
{
}
pub trait AbelianGroup: Group {}
impl<T, Op> AbelianGroup for T
where T: Magma<Operation = Op>,
Op: Devisiablility<T> + Associativity<T> + Identity<T> + Commutativity<T>
{
}