CloneFunctor

This commit is contained in:
AF 2023-03-12 08:31:10 +00:00
parent d3ec497ec4
commit bd349c96e8
3 changed files with 217 additions and 24 deletions

View File

@ -1,4 +1,5 @@
pub mod classes; pub mod classes;
pub mod clone_func;
pub mod copy_func; pub mod copy_func;
#[cfg(test)] #[cfg(test)]
pub mod test_suite; pub mod test_suite;

180
src/func/clone_func.rs Normal file
View File

@ -0,0 +1,180 @@
use crate::func::*;
pub trait CloneWeakFunctor {
type ClF<'a, A: Clone>;
}
impl<T: WeakFunctor> CloneWeakFunctor for T {
type ClF<'a, A: Clone> = T::F<'a, A>;
}
pub trait CloneFunctor: CloneWeakFunctor {
fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Fn(A) -> B>(
f: F,
fa: Self::ClF<'a, A>,
) -> Self::ClF<'a, B>;
fn clone_replace<'a, A: 'a + Clone, B: 'a + Clone>(
fa: Self::ClF<'a, A>,
b: B,
) -> Self::ClF<'a, B> {
Self::clone_fmap(move |_| b.clone(), fa)
}
fn clone_void<'a, A: 'a + Clone>(fa: Self::ClF<'a, A>) -> Self::ClF<'a, ()> {
Self::clone_replace(fa, ())
}
}
impl<T: Functor> CloneFunctor for T {
fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Fn(A) -> B>(
f: F,
fa: Self::ClF<'a, A>,
) -> Self::ClF<'a, B> {
Self::fmap(f, fa)
}
fn clone_replace<'a, A: 'a + Clone, B: 'a + Clone>(
fa: Self::ClF<'a, A>,
b: B,
) -> Self::ClF<'a, B> {
Self::replace(fa, b)
}
fn clone_void<'a, A: 'a + Clone>(fa: Self::ClF<'a, A>) -> Self::ClF<'a, ()> {
Self::void(fa)
}
}
pub trait CloneApplicativeSeq: CloneFunctor {
fn clone_seq<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Clone + Fn(A) -> B>(
ff: Self::ClF<'a, F>,
fa: Self::ClF<'a, A>,
) -> Self::ClF<'a, B>;
fn _clone_la2<
'a,
A: 'a + Clone,
B: 'a + Clone,
C: 'a + Clone,
F: 'a + Clone + Fn(A, B) -> C,
>(
f: F,
fa: Self::ClF<'a, A>,
fb: Self::ClF<'a, B>,
) -> Self::ClF<'a, C> {
Self::clone_seq(
Self::clone_fmap(
move |a| {
let cf = f.clone();
move |b: B| cf(a.clone(), b.clone())
},
fa,
),
fb,
)
}
}
impl<T: ApplicativeSeq> CloneApplicativeSeq for T {
fn clone_seq<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Clone + Fn(A) -> B>(
ff: Self::ClF<'a, F>,
fa: Self::ClF<'a, A>,
) -> Self::ClF<'a, B> {
Self::seq(ff, fa)
}
}
pub trait CloneApplicativeLA2: CloneFunctor {
fn clone_la2<'a, A: 'a + Clone, B: 'a + Clone, C: 'a + Clone, F: 'a + Clone + Fn(A, B) -> C>(
f: F,
fa: Self::ClF<'a, A>,
fb: Self::ClF<'a, B>,
) -> Self::ClF<'a, C>;
fn _clone_seq<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Clone + Fn(A) -> B>(
ff: Self::ClF<'a, F>,
fa: Self::ClF<'a, A>,
) -> Self::ClF<'a, B> {
Self::clone_la2(|f, a| f(a), ff, fa)
}
}
impl<T: ApplicativeLA2> CloneApplicativeLA2 for T {
fn clone_la2<'a, A: 'a + Clone, B: 'a + Clone, C: 'a + Clone, F: 'a + Clone + Fn(A, B) -> C>(
f: F,
fa: Self::ClF<'a, A>,
fb: Self::ClF<'a, B>,
) -> Self::ClF<'a, C> {
Self::la2(f, fa, fb)
}
}
pub trait CloneApplicative: CloneFunctor + CloneApplicativeSeq + CloneApplicativeLA2 {
fn clone_pure<'a, A: 'a + Clone>(a: A) -> Self::ClF<'a, A>;
fn clone_discard_first<'a, A: 'a + Clone, B: 'a + Clone>(
fa: Self::ClF<'a, A>,
fb: Self::ClF<'a, B>,
) -> Self::ClF<'a, B> {
Self::clone_seq(Self::clone_replace(fa, |b| b), fb)
}
fn clone_discard_second<'a, A: 'a + Clone, B: 'a + Clone>(
fa: Self::ClF<'a, A>,
fb: Self::ClF<'a, B>,
) -> Self::ClF<'a, A> {
Self::clone_la2(|a, _| a, fa, fb)
}
}
impl<T: Applicative> CloneApplicative for T {
fn clone_pure<'a, A: 'a + Clone>(a: A) -> Self::ClF<'a, A> {
Self::pure(a)
}
fn clone_discard_first<'a, A: 'a + Clone, B: 'a + Clone>(
fa: Self::ClF<'a, A>,
fb: Self::ClF<'a, B>,
) -> Self::ClF<'a, B> {
Self::discard_first(fa, fb)
}
fn clone_discard_second<'a, A: 'a + Clone, B: 'a + Clone>(
fa: Self::ClF<'a, A>,
fb: Self::ClF<'a, B>,
) -> Self::ClF<'a, A> {
Self::discard_second(fa, fb)
}
}
pub trait CloneMonad: CloneApplicative {
fn clone_bind<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Clone + Fn(A) -> Self::ClF<'a, B>>(
fa: Self::ClF<'a, A>,
f: F,
) -> Self::ClF<'a, B>;
fn clone_join<'a, A: 'a + Clone>(ffa: Self::ClF<'a, Self::ClF<'a, A>>) -> Self::ClF<'a, A>
where
Self::ClF<'a, A>: 'a + Clone,
{
// ugly
Self::clone_bind(ffa, |fa| fa)
}
}
impl<T: Monad> CloneMonad for T {
fn clone_bind<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Clone + Fn(A) -> Self::ClF<'a, B>>(
fa: Self::ClF<'a, A>,
f: F,
) -> Self::ClF<'a, B> {
T::bind(fa, f)
}
fn clone_join<'a, A: 'a + Clone>(ffa: Self::ClF<'a, Self::ClF<'a, A>>) -> Self::ClF<'a, A>
where
Self::ClF<'a, A>: 'a + Clone,
{
T::join(ffa)
}
}

View File

@ -1,9 +1,13 @@
use crate::func::*; use crate::func::clone_func::*;
pub trait CopyWeakFunctor { pub trait CopyWeakFunctor {
type CF<'a, A: Copy>; type CF<'a, A: Copy>;
} }
impl<T: CloneWeakFunctor> CopyWeakFunctor for T {
type CF<'a, A: Copy> = T::ClF<'a, A>;
}
pub trait CopyFunctor: CopyWeakFunctor { pub trait CopyFunctor: CopyWeakFunctor {
fn copy_fmap<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Fn(A) -> B>( fn copy_fmap<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Fn(A) -> B>(
f: F, f: F,
@ -19,24 +23,20 @@ pub trait CopyFunctor: CopyWeakFunctor {
} }
} }
impl<T: WeakFunctor> CopyWeakFunctor for T { impl<T: CloneFunctor> CopyFunctor for T {
type CF<'a, A: Copy> = T::F<'a, A>;
}
impl<T: Functor> CopyFunctor for T {
fn copy_fmap<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Fn(A) -> B>( fn copy_fmap<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Fn(A) -> B>(
f: F, f: F,
fa: Self::CF<'a, A>, fa: Self::CF<'a, A>,
) -> Self::CF<'a, B> { ) -> Self::CF<'a, B> {
Self::fmap(f, fa) 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> { fn copy_replace<'a, A: 'a + Copy, B: 'a + Copy>(fa: Self::CF<'a, A>, b: B) -> Self::CF<'a, B> {
Self::replace(fa, b) Self::clone_replace(fa, b)
} }
fn copy_void<'a, A: 'a + Copy>(fa: Self::CF<'a, A>) -> Self::CF<'a, ()> { fn copy_void<'a, A: 'a + Copy>(fa: Self::CF<'a, A>) -> Self::CF<'a, ()> {
Self::void(fa) Self::clone_void(fa)
} }
} }
@ -55,12 +55,12 @@ pub trait CopyApplicativeSeq: CopyFunctor {
} }
} }
impl<T: ApplicativeSeq> CopyApplicativeSeq for T { impl<T: CloneApplicativeSeq> CopyApplicativeSeq for T {
fn copy_seq<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> B>( fn copy_seq<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> B>(
ff: Self::CF<'a, F>, ff: Self::CF<'a, F>,
fa: Self::CF<'a, A>, fa: Self::CF<'a, A>,
) -> Self::CF<'a, B> { ) -> Self::CF<'a, B> {
Self::seq(ff, fa) Self::clone_seq(ff, fa)
} }
} }
@ -79,39 +79,51 @@ pub trait CopyApplicativeLA2: CopyFunctor {
} }
} }
impl<T: ApplicativeLA2> CopyApplicativeLA2 for T { 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>( fn copy_la2<'a, A: 'a + Copy, B: 'a + Copy, C: 'a + Copy, F: 'a + Copy + Fn(A, B) -> C>(
f: F, f: F,
fa: Self::CF<'a, A>, fa: Self::CF<'a, A>,
fb: Self::CF<'a, B>, fb: Self::CF<'a, B>,
) -> Self::CF<'a, C> { ) -> Self::CF<'a, C> {
Self::la2(f, fa, fb) Self::clone_la2(f, fa, fb)
} }
} }
pub trait CopyApplicative: CopyFunctor + CopyApplicativeSeq + CopyApplicativeLA2 { pub trait CopyApplicative: CopyFunctor + CopyApplicativeSeq + CopyApplicativeLA2 {
fn copy_pure<'a, A: 'a + Copy>(a: A) -> Self::CF<'a, A>; 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> { 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) 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> { 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) Self::copy_la2(|a, _| a, fa, fb)
} }
} }
impl<T: Applicative> CopyApplicative for T { impl<T: CloneApplicative> CopyApplicative for T {
fn copy_pure<'a, A: 'a + Copy>(a: A) -> Self::CF<'a, A> { fn copy_pure<'a, A: 'a + Copy>(a: A) -> Self::CF<'a, A> {
Self::pure(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> { fn copy_discard_first<'a, A: 'a + Copy, B: 'a + Copy>(
Self::discard_first(fa, fb) 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> { fn copy_discard_second<'a, A: 'a + Copy, B: 'a + Copy>(
Self::discard_second(fa, fb) fa: Self::CF<'a, A>,
fb: Self::CF<'a, B>,
) -> Self::CF<'a, A> {
Self::clone_discard_second(fa, fb)
} }
} }
@ -130,18 +142,18 @@ pub trait CopyMonad: CopyApplicative {
} }
} }
impl<T: Monad> CopyMonad for T { 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>>( fn copy_bind<'a, A: 'a + Copy, B: 'a + Copy, F: 'a + Copy + Fn(A) -> Self::CF<'a, B>>(
fa: Self::CF<'a, A>, fa: Self::CF<'a, A>,
f: F, f: F,
) -> Self::CF<'a, B> { ) -> Self::CF<'a, B> {
T::bind(fa, f) T::clone_bind(fa, f)
} }
fn copy_join<'a, A: 'a + Copy>(ffa: Self::CF<'a, Self::CF<'a, A>>) -> Self::CF<'a, A> fn copy_join<'a, A: 'a + Copy>(ffa: Self::CF<'a, Self::CF<'a, A>>) -> Self::CF<'a, A>
where where
Self::CF<'a, A>: 'a + Copy, Self::CF<'a, A>: 'a + Copy,
{ {
T::join(ffa) T::clone_join(ffa)
} }
} }