160 lines
4.4 KiB
Rust
160 lines
4.4 KiB
Rust
use crate::func::clone_func::*;
|
|
|
|
pub trait CopyWeakFunctor {
|
|
type CF<'a, A: Copy>;
|
|
}
|
|
|
|
impl<T: CloneWeakFunctor> CopyWeakFunctor for T {
|
|
type CF<'a, A: Copy> = T::ClF<'a, A>;
|
|
}
|
|
|
|
pub trait CopyFunctor: CopyWeakFunctor {
|
|
fn copy_fmap<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Fn(A) -> B>(
|
|
f: F,
|
|
fa: Self::CF<'a, A>,
|
|
) -> Self::CF<'a, B>;
|
|
|
|
fn copy_replace<'a, A: 'a + Copy, B: 'a + Copy>(fa: Self::CF<'a, A>, b: B) -> Self::CF<'a, B> {
|
|
Self::copy_fmap(move |_| b, fa)
|
|
}
|
|
|
|
fn copy_void<'a, A: 'a + Copy>(fa: Self::CF<'a, A>) -> Self::CF<'a, ()> {
|
|
Self::copy_replace(fa, ())
|
|
}
|
|
}
|
|
|
|
impl<T: CloneFunctor> CopyFunctor for T {
|
|
fn copy_fmap<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Fn(A) -> B>(
|
|
f: F,
|
|
fa: Self::CF<'a, A>,
|
|
) -> Self::CF<'a, B> {
|
|
Self::clone_fmap(f, fa)
|
|
}
|
|
|
|
fn copy_replace<'a, A: 'a + Copy, B: 'a + Copy>(fa: Self::CF<'a, A>, b: B) -> Self::CF<'a, B> {
|
|
Self::clone_replace(fa, b)
|
|
}
|
|
|
|
fn copy_void<'a, A: 'a + Copy>(fa: Self::CF<'a, A>) -> Self::CF<'a, ()> {
|
|
Self::clone_void(fa)
|
|
}
|
|
}
|
|
|
|
pub trait CopyApplicativeSeq: CopyFunctor {
|
|
fn copy_seq<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> B>(
|
|
ff: Self::CF<'a, F>,
|
|
fa: Self::CF<'a, A>,
|
|
) -> Self::CF<'a, B>;
|
|
|
|
fn _copy_la2<'a, A: 'a + Copy, B: 'a + Copy, C: 'a + Copy, F: 'a + Copy + Fn(A, B) -> C>(
|
|
f: F,
|
|
fa: Self::CF<'a, A>,
|
|
fb: Self::CF<'a, B>,
|
|
) -> Self::CF<'a, C> {
|
|
Self::copy_seq(Self::copy_fmap(move |a| move |b| f(a, b), fa), fb)
|
|
}
|
|
}
|
|
|
|
impl<T: CloneApplicativeSeq> CopyApplicativeSeq for T {
|
|
fn copy_seq<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> B>(
|
|
ff: Self::CF<'a, F>,
|
|
fa: Self::CF<'a, A>,
|
|
) -> Self::CF<'a, B> {
|
|
Self::clone_seq(ff, fa)
|
|
}
|
|
}
|
|
|
|
pub trait CopyApplicativeLA2: CopyFunctor {
|
|
fn copy_la2<'a, A: 'a + Copy, B: 'a + Copy, C: 'a + Copy, F: 'a + Copy + Fn(A, B) -> C>(
|
|
f: F,
|
|
fa: Self::CF<'a, A>,
|
|
fb: Self::CF<'a, B>,
|
|
) -> Self::CF<'a, C>;
|
|
|
|
fn _copy_seq<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> B>(
|
|
ff: Self::CF<'a, F>,
|
|
fa: Self::CF<'a, A>,
|
|
) -> Self::CF<'a, B> {
|
|
Self::copy_la2(|f, a| f(a), ff, fa)
|
|
}
|
|
}
|
|
|
|
impl<T: CloneApplicativeLA2> CopyApplicativeLA2 for T {
|
|
fn copy_la2<'a, A: 'a + Copy, B: 'a + Copy, C: 'a + Copy, F: 'a + Copy + Fn(A, B) -> C>(
|
|
f: F,
|
|
fa: Self::CF<'a, A>,
|
|
fb: Self::CF<'a, B>,
|
|
) -> Self::CF<'a, C> {
|
|
Self::clone_la2(f, fa, fb)
|
|
}
|
|
}
|
|
|
|
pub trait CopyApplicative: CopyFunctor + CopyApplicativeSeq + CopyApplicativeLA2 {
|
|
fn copy_pure<'a, A: 'a + Copy>(a: A) -> Self::CF<'a, A>;
|
|
|
|
fn copy_discard_first<'a, A: 'a + Copy, B: 'a + Copy>(
|
|
fa: Self::CF<'a, A>,
|
|
fb: Self::CF<'a, B>,
|
|
) -> Self::CF<'a, B> {
|
|
Self::copy_seq(Self::copy_replace(fa, |b| b), fb)
|
|
}
|
|
|
|
fn copy_discard_second<'a, A: 'a + Copy, B: 'a + Copy>(
|
|
fa: Self::CF<'a, A>,
|
|
fb: Self::CF<'a, B>,
|
|
) -> Self::CF<'a, A> {
|
|
Self::copy_la2(|a, _| a, fa, fb)
|
|
}
|
|
}
|
|
|
|
impl<T: CloneApplicative> CopyApplicative for T {
|
|
fn copy_pure<'a, A: 'a + Copy>(a: A) -> Self::CF<'a, A> {
|
|
Self::clone_pure(a)
|
|
}
|
|
|
|
fn copy_discard_first<'a, A: 'a + Copy, B: 'a + Copy>(
|
|
fa: Self::CF<'a, A>,
|
|
fb: Self::CF<'a, B>,
|
|
) -> Self::CF<'a, B> {
|
|
Self::clone_discard_first(fa, fb)
|
|
}
|
|
|
|
fn copy_discard_second<'a, A: 'a + Copy, B: 'a + Copy>(
|
|
fa: Self::CF<'a, A>,
|
|
fb: Self::CF<'a, B>,
|
|
) -> Self::CF<'a, A> {
|
|
Self::clone_discard_second(fa, fb)
|
|
}
|
|
}
|
|
|
|
pub trait CopyMonad: CopyApplicative {
|
|
fn copy_bind<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> Self::CF<'a, B>>(
|
|
fa: Self::CF<'a, A>,
|
|
f: F,
|
|
) -> Self::CF<'a, B>;
|
|
|
|
fn copy_join<'a, A: 'a + Copy>(ffa: Self::CF<'a, Self::CF<'a, A>>) -> Self::CF<'a, A>
|
|
where
|
|
Self::CF<'a, A>: 'a + Copy,
|
|
{
|
|
// ugly
|
|
Self::copy_bind(ffa, |fa| fa)
|
|
}
|
|
}
|
|
|
|
impl<T: CloneMonad> CopyMonad for T {
|
|
fn copy_bind<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> Self::CF<'a, B>>(
|
|
fa: Self::CF<'a, A>,
|
|
f: F,
|
|
) -> Self::CF<'a, B> {
|
|
T::clone_bind(fa, f)
|
|
}
|
|
|
|
fn copy_join<'a, A: 'a + Copy>(ffa: Self::CF<'a, Self::CF<'a, A>>) -> Self::CF<'a, A>
|
|
where
|
|
Self::CF<'a, A>: 'a + Copy,
|
|
{
|
|
T::clone_join(ffa)
|
|
}
|
|
}
|