#![allow(dead_code, unused)]
#![feature(type_ascription)]
use std::collections::linked_list::LinkedList;
use std::collections::vec_deque::VecDeque;
use std::collections::{BinaryHeap, BTreeSet, HashSet};
pub trait Higher<A> {
type B; type C; }
#[macro_export]
macro_rules! lift {
($t:ident) => {
impl<A,C> Higher<A> for $t<C> {
type B = C;
type C = $t<A>;
}
}
}
lift!(Vec);
lift!(Option);
lift!(Box);
lift!(LinkedList);
lift!(BinaryHeap);
lift!(BTreeSet);
lift!(VecDeque);
lift!(HashSet);
pub trait SemiGroup {
type A;
fn add(&self, b: &Self::A) -> Self::A;
}
pub trait Monoid : SemiGroup {
fn id() -> Self::A;
}
pub trait Foldable {
type A; fn foldr<F>(&self, accum: Self::A, f: F) -> Self::A
where F: FnMut(Self::A, &Self::A) -> Self::A;
}
pub trait Functor<A>: Higher<A> {
fn fmap<F>(&self, f: F) -> Self::C where F: Fn(&Self::B) -> A;
}
pub trait Applicative<A> : Higher<A> {
fn raise(x: A) -> Self::C where Self: Higher<A, B=A>;
fn apply<F>(&self, <Self as Higher<F>>::C) -> <Self as Higher<A>>::C where F: Fn(&<Self as Higher<A>>::B) -> A, Self: Higher<F>; }
pub trait Monad<A>: Higher<A> {
fn lift(x: A) -> Self::C where Self: Higher<A, B = A>;
fn bind<F>(&self, F) -> Self::C where F: FnMut(&Self::B) -> Self::C;
}
#[macro_export]
macro_rules! functorize {
($t:ident) => {
impl<A,B> Functor<A> for $t<B> {
fn fmap<F>(&self, f:F) -> $t<A> where F: Fn(&B) -> A {
self.iter().map(f).collect::<$t<A>>()
}
}
}
}
#[macro_export]
macro_rules! monoid_num {
($t:ident, $z:expr) => {
impl Monoid for $t {
fn id() -> Self::A {
$z
}
}
}
}
#[macro_export]
macro_rules! monoid {
($t:ident) => {
impl<T: Clone> Monoid for $t<T> {
fn id() -> Self::A {
$t::new()
}
}
}
}
#[macro_export]
macro_rules! monoid_ord {
($t:ident) => {
impl<T: Clone + Ord> Monoid for $t<T> {
fn id() -> Self::A {
$t::new()
}
}
}
}
#[macro_export]
macro_rules! foldable {
($t:ident) => {
impl<T> Foldable for $t<T> {
type A = T;
fn foldr<F>(&self, accum: Self::A, f: F) -> Self::A
where F: FnMut(Self::A, &Self::A) -> Self::A
{
self.iter().fold(accum, f)
}
}
}
}
#[macro_export]
macro_rules! semigroup_num {
($t:ident) => {
impl SemiGroup for $t {
type A = $t;
fn add(&self, b: &Self::A) -> Self::A {
self + b
}
}
}
}
#[macro_export]
macro_rules! semigroup {
($t:ident) => {
impl<T: Clone> SemiGroup for $t<T> {
type A = $t<T>;
fn add(&self, b: &Self::A) -> Self::A {
let mut ret = $t::new();
ret.extend(self.iter().cloned());
ret.extend(b.iter().cloned());
ret
}
}
}
}
#[macro_export]
macro_rules! semigroup_ord {
($t:ident) => {
impl<T: Clone + Ord> SemiGroup for $t<T> {
type A = $t<T>;
fn add(&self, b: &Self::A) -> Self::A {
let mut ret = $t::new();
ret.extend(self.iter().cloned());
ret.extend(b.iter().cloned());
ret
}
}
}
}