pub mod classes; pub mod clone_func; pub mod copy_func; #[cfg(test)] pub mod test_suite; #[cfg(test)] pub mod tests; pub trait WeakFunctor { type F<'a, A: 'a> : 'a; } /// Rust-specific implementation of [Functor], respecting `move` semantics. /// /// Cannot insantiate for e.g. multi-element collections: /// ```compile_fail /// use radn_rs::func::*; /// /// struct VecClass; /// /// impl WeakFunctor for VecClass { /// type F<'a, A> = Vec; /// } /// /// impl Functor for VecClass { /// fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> /// fa.into_iter().map(f).collect() /// } /// } /// ``` /// Why does it fail to compile? `.map` expects `FnMut` (or we can think of it being `Fn`, doesn't matter here). But what we provide it (`f`) is /// /// For Haskell-style Functors, use [clone_func::CloneFunctor] instead. /// ``` /// use radn_rs::func::clone_func::*; /// /// struct VecClass; /// /// impl CloneWeakFunctor for VecClass { /// type ClF<'a, A: Clone> = Vec; /// } /// /// impl CloneFunctor for VecClass { /// fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone>( /// f: impl 'a + Fn(A) -> B, /// fa: Self::ClF<'a, A>, /// ) -> Self::ClF<'a, B> { /// fa.into_iter().map(f).collect() /// } /// } /// ``` pub trait Functor: WeakFunctor { fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> where Self: 'a; fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> where Self: 'a, { Self::fmap(|_| b, fa) } fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> where Self: 'a, { Self::replace(fa, ()) } } pub fn fmap<'a, T: 'a + Functor, A: 'a, B: 'a>( f: impl 'a + FnOnce(A) -> B, ) -> impl FnOnce(T::F<'a, A>) -> T::F<'a, B> { move |fa| T::fmap(f, fa) } pub trait ApplicativeSeq: Functor { fn seq<'a, A: 'a, B: 'a>( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> where Self: 'a; fn _la2<'a, A: 'a, B: 'a, C: 'a>( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, ) -> Self::F<'a, C> where Self: 'a, { Self::seq(Self::fmap(|a| |b| f(a, b), fa), fb) } } pub trait ApplicativeLA2: Functor { fn la2<'a, A: 'a, B: 'a, C: 'a>( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, ) -> Self::F<'a, C> where Self: 'a; fn _seq<'a, A: 'a, B: 'a>( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> where Self: 'a, { Self::la2(|f, a| f(a), ff, fa) } } pub trait Applicative: Functor + ApplicativeSeq + ApplicativeLA2 { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A>; fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> where Self: 'a, { Self::seq(Self::replace(fa, |b| b), fb) } fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> where Self: 'a, { Self::la2(|a, _| a, fa, fb) } } pub trait Monad: Applicative { fn bind<'a, A: 'a, B: 'a>( fa: Self::F<'a, A>, f: impl 'a + FnOnce(A) -> Self::F<'a, B>, ) -> Self::F<'a, B> where Self: 'a; fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> where Self::F<'a, A>: 'a, Self: 'a, { Self::bind(ffa, |fa| fa) } } pub trait MonadFail: Monad { fn fail<'a, A>(e: E) -> Self::F<'a, A>; } pub trait Alternative: Applicative { fn empty<'a, A>() -> Self::F<'a, A>; fn add<'a, A>(fa: Self::F<'a, A>, fb: Self::F<'a, A>) -> Self::F<'a, A>; }