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, 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 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 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 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 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 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) } }