pub trait CloneWeakFunctor { type ClF<'a, A: Clone>: Clone; } 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, ()) } } 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) }, fa, ), fb, ) } } 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) } } 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) } } 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, { // ugly Self::clone_bind(ffa, |fa| fa) } }