100 lines
2.7 KiB
Rust
100 lines
2.7 KiB
Rust
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)
|
|
}
|
|
}
|