From bd349c96e8e5e02987684cb5c224251701830c4c Mon Sep 17 00:00:00 2001 From: timofey Date: Sun, 12 Mar 2023 08:31:10 +0000 Subject: [PATCH] CloneFunctor --- src/func.rs | 1 + src/func/clone_func.rs | 180 +++++++++++++++++++++++++++++++++++++++++ src/func/copy_func.rs | 60 ++++++++------ 3 files changed, 217 insertions(+), 24 deletions(-) create mode 100644 src/func/clone_func.rs diff --git a/src/func.rs b/src/func.rs index 8a22b8f..ed483bc 100644 --- a/src/func.rs +++ b/src/func.rs @@ -1,4 +1,5 @@ pub mod classes; +pub mod clone_func; pub mod copy_func; #[cfg(test)] pub mod test_suite; diff --git a/src/func/clone_func.rs b/src/func/clone_func.rs new file mode 100644 index 0000000..7131377 --- /dev/null +++ b/src/func/clone_func.rs @@ -0,0 +1,180 @@ +use crate::func::*; + +pub trait CloneWeakFunctor { + type ClF<'a, A: Clone>; +} + +impl 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 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 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 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 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 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) + } +} diff --git a/src/func/copy_func.rs b/src/func/copy_func.rs index 0a8d8af..d70aefa 100644 --- a/src/func/copy_func.rs +++ b/src/func/copy_func.rs @@ -1,9 +1,13 @@ -use crate::func::*; +use crate::func::clone_func::*; pub trait CopyWeakFunctor { type CF<'a, A: Copy>; } +impl 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, @@ -19,24 +23,20 @@ pub trait CopyFunctor: CopyWeakFunctor { } } -impl CopyWeakFunctor for T { - type CF<'a, A: Copy> = T::F<'a, A>; -} - -impl CopyFunctor for T { +impl 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::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> { - Self::replace(fa, b) + Self::clone_replace(fa, b) } 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 CopyApplicativeSeq for T { +impl 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::seq(ff, fa) + Self::clone_seq(ff, fa) } } @@ -79,39 +79,51 @@ pub trait CopyApplicativeLA2: CopyFunctor { } } -impl CopyApplicativeLA2 for T { +impl 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::la2(f, fa, fb) + 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> { + 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> { + 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 CopyApplicative for T { +impl CopyApplicative for T { 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> { - Self::discard_first(fa, fb) + 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::discard_second(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) } } @@ -130,18 +142,18 @@ pub trait CopyMonad: CopyApplicative { } } -impl CopyMonad for T { +impl 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::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> where Self::CF<'a, A>: 'a + Copy, { - T::join(ffa) + T::clone_join(ffa) } }