radn-rs/src/func/copy_func.rs
2023-04-21 20:58:13 +00:00

87 lines
2.5 KiB
Rust

//! Equivalent of [`crate::func`] for [`Copy`]/[`Fn`] Category.
//! Not well maintained due to not being used in the main RADN code base.
//!
//! See also: [`super::clone_func`]
pub trait CopyWeakFunctor {
type CF<'a, A: Copy>: Copy;
}
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, ())
}
}
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)
}
}
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)
}
}
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)
}
}
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,
{
// ugly
Self::copy_bind(ffa, |fa| fa)
}
}