use std::{ops, num, iter};
use super::groups::*;
pub struct Add;
impl<T> Closure<T> for Add
where T: ops::Add<Output = T>
{
fn apply(lhs: T, rhs: T) -> T {
lhs + rhs
}
}
unsafe impl Associativity<isize> for Add {}
unsafe impl Associativity<i8> for Add {}
unsafe impl Associativity<i16> for Add {}
unsafe impl Associativity<i32> for Add {}
unsafe impl Associativity<i64> for Add {}
unsafe impl Associativity<usize> for Add {}
unsafe impl Associativity<u8> for Add {}
unsafe impl Associativity<u16> for Add {}
unsafe impl Associativity<u32> for Add {}
unsafe impl Associativity<u64> for Add {}
unsafe impl Associativity<f32> for Add {}
unsafe impl Associativity<f64> for Add {}
unsafe impl Commutativity<isize> for Add {}
unsafe impl Commutativity<i8> for Add {}
unsafe impl Commutativity<i16> for Add {}
unsafe impl Commutativity<i32> for Add {}
unsafe impl Commutativity<i64> for Add {}
unsafe impl Commutativity<usize> for Add {}
unsafe impl Commutativity<u8> for Add {}
unsafe impl Commutativity<u16> for Add {}
unsafe impl Commutativity<u32> for Add {}
unsafe impl Commutativity<u64> for Add {}
unsafe impl Commutativity<f32> for Add {}
unsafe impl Commutativity<f64> for Add {}
unsafe impl<T> Identity<T> for Add
where T: num::Zero + ops::Add<Output = T>
{
fn identity() -> T {
<T as num::Zero>::zero()
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
pub struct Sum<T>(pub T);
impl<T> ops::Add for Sum<T>
where T: ops::Add<Output = T>
{
type Output = Sum<T>;
fn add(self, rhs: Self) -> Self {
Sum(self.0.add(rhs.0))
}
}
unsafe impl<T> Associativity<Sum<T>> for Add
where Add: Associativity<T>,
T: ops::Add<Output = T>
{
}
unsafe impl<T> Identity<Sum<T>> for Add
where Add: Identity<T>,
T: ops::Add<Output = T>
{
fn identity() -> Sum<T> {
Sum(Self::identity())
}
}
impl<T> Magma for Sum<T>
where T: ops::Add<Output = T>
{
type Operation = Add;
}
pub struct Mul;
impl<T> Closure<T> for Mul
where T: ops::Mul<Output = T>
{
fn apply(lhs: T, rhs: T) -> T {
lhs * rhs
}
}
unsafe impl Associativity<isize> for Mul {}
unsafe impl Associativity<i8> for Mul {}
unsafe impl Associativity<i16> for Mul {}
unsafe impl Associativity<i32> for Mul {}
unsafe impl Associativity<i64> for Mul {}
unsafe impl Associativity<usize> for Mul {}
unsafe impl Associativity<u8> for Mul {}
unsafe impl Associativity<u16> for Mul {}
unsafe impl Associativity<u32> for Mul {}
unsafe impl Associativity<u64> for Mul {}
unsafe impl Associativity<f32> for Mul {}
unsafe impl Associativity<f64> for Mul {}
unsafe impl Commutativity<isize> for Mul {}
unsafe impl Commutativity<i8> for Mul {}
unsafe impl Commutativity<i16> for Mul {}
unsafe impl Commutativity<i32> for Mul {}
unsafe impl Commutativity<i64> for Mul {}
unsafe impl Commutativity<usize> for Mul {}
unsafe impl Commutativity<u8> for Mul {}
unsafe impl Commutativity<u16> for Mul {}
unsafe impl Commutativity<u32> for Mul {}
unsafe impl Commutativity<u64> for Mul {}
unsafe impl Commutativity<f32> for Mul {}
unsafe impl Commutativity<f64> for Mul {}
unsafe impl<T> Identity<T> for Mul
where T: num::One + ops::Mul<Output = T>
{
fn identity() -> T {
<T as num::One>::one()
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
pub struct Prod<T>(pub T);
impl<T> ops::Mul for Prod<T>
where T: ops::Mul<Output = T>
{
type Output = Prod<T>;
fn mul(self, rhs: Self) -> Self {
Prod(self.0.mul(rhs.0))
}
}
unsafe impl<T> Associativity<Prod<T>> for Mul
where Mul: Associativity<T>,
T: ops::Mul<Output = T>
{
}
unsafe impl<T> Identity<Prod<T>> for Mul
where Mul: Identity<T>,
T: ops::Mul<Output = T>
{
fn identity() -> Prod<T> {
Prod(Self::identity())
}
}
impl<T> Magma for Prod<T>
where T: ops::Mul<Output = T>
{
type Operation = Mul;
}
pub struct Concat;
impl<U, T> Closure<T> for Concat
where T: iter::IntoIterator<Item = U> + iter::FromIterator<U>
{
fn apply(lhs: T, rhs: T) -> T {
lhs.into_iter().chain(rhs.into_iter()).collect()
}
}
unsafe impl<U, T> Associativity<T> for Concat
where T: iter::IntoIterator<Item = U> + iter::FromIterator<U>
{
}
unsafe impl<U, T> Identity<T> for Concat
where T: iter::IntoIterator<Item = U> + iter::FromIterator<U>
{
fn identity() -> T {
T::from_iter(iter::empty())
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
pub struct Sequence<T>(pub T);
impl<U, T> Closure<Sequence<T>> for Concat
where T: iter::IntoIterator<Item = U> + iter::FromIterator<U>
{
fn apply(lhs: Sequence<T>, rhs: Sequence<T>) -> Sequence<T> {
let (Sequence(lhs), Sequence(rhs)) = (lhs, rhs);
Sequence(lhs.into_iter().chain(rhs.into_iter()).collect())
}
}
unsafe impl<U, T> Associativity<Sequence<T>> for Concat
where T: iter::IntoIterator<Item = U> + iter::FromIterator<U>
{
}
unsafe impl<U, T> Identity<Sequence<T>> for Concat
where T: iter::IntoIterator<Item = U> + iter::FromIterator<U>
{
fn identity() -> Sequence<T> {
Sequence(iter::empty().collect())
}
}
impl<T, Y> Magma for Sequence<T>
where T: iter::IntoIterator<Item = Y> + iter::FromIterator<Y>
{
type Operation = Concat;
}