diff --git a/src/func.rs b/src/func.rs index d22e058..438c1fa 100644 --- a/src/func.rs +++ b/src/func.rs @@ -228,7 +228,7 @@ pub trait LocalFunctor: WeakFunctor { Self: 'a; /// Stuff wrapped result into another functor. - fn stuff<'a, A: 'a, U: 'a + Functor>(fa: Self::F<'a, U::F<'a, A>>) -> U::F<'a, Self::F<'a, A>> + fn stuff<'a, A: 'a, T: 'a + Pure>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> where Self: 'a; } diff --git a/src/func/classes/composition.rs b/src/func/classes/composition.rs index e2775be..181d01f 100644 --- a/src/func/classes/composition.rs +++ b/src/func/classes/composition.rs @@ -120,3 +120,19 @@ impl Monad for CompositionClass { U::join(U::fmap(|ufa| U::fmap(V::join, V::stuff::<_, U>(ufa)), ffa)) } } + +impl LocalFunctor for CompositionClass { + fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState>) -> IState> + where + Self: 'a, + { + U::unstuff(U::fmap(V::unstuff, state)) + } + + fn stuff<'a, A: 'a, T: 'a + Pure>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> + where + Self: 'a, + { + U::stuff::<_, T>(U::fmap(V::stuff::<_, T>, fa)) + } +} diff --git a/src/func/classes/option.rs b/src/func/classes/option.rs index a52d148..7758b95 100644 --- a/src/func/classes/option.rs +++ b/src/func/classes/option.rs @@ -99,6 +99,29 @@ impl Monad for OptionClass { } } +impl LocalFunctor for OptionClass { + fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState>) -> IState> + where + Self: 'a, + { + match state { + Some(IState::Pending(a)) => IState::Pending(a), + Some(IState::Done(b)) => IState::Done(Some(b)), + None => IState::Done(None), + } + } + + fn stuff<'a, A: 'a, T: 'a + Pure>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> + where + Self: 'a, + { + match fa { + Some(ua) => T::fmap(Some, ua), + None => T::pure(None), + } + } +} + #[cfg(test)] mod option_tests { use super::{test_suite, tests, Functor}; diff --git a/src/func/classes/result.rs b/src/func/classes/result.rs index 14e1a77..b3fd327 100644 --- a/src/func/classes/result.rs +++ b/src/func/classes/result.rs @@ -9,24 +9,33 @@ use crate::func::*; -pub struct ResultClass(E); +pub struct ResultClass(E); impl WeakFunctor for ResultClass { - type F<'a, A: 'a> = Result; + type F<'a, A: 'a> = Result where Self: 'a; } impl Functor for ResultClass { - fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> { + 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, + { fa.map(f) } - fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> + where + Self: 'a, + { fa.map(|_| b) } } impl Pure for ResultClass { - fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { + fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> + where + Self: 'a, + { Ok(a) } } @@ -35,7 +44,10 @@ impl ApplicativeSeq for ResultClass { 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> { + ) -> Self::F<'a, B> + where + Self: 'a, + { Self::pure(ff?(fa?)) } } @@ -45,7 +57,10 @@ impl ApplicativeLA2 for ResultClass { f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> { + ) -> Self::F<'a, C> + where + Self: 'a, + { Self::pure(f(fa?, fb?)) } } @@ -60,12 +75,18 @@ impl ApplicativeTuple for ResultClass { } impl Applicative for ResultClass { - fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + 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, + { fa?; fb } - fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + 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, + { fb?; fa } @@ -75,7 +96,10 @@ impl Monad for ResultClass { 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> { + ) -> Self::F<'a, B> + where + Self: 'a, + { f(fa?) } @@ -94,11 +118,37 @@ impl Monad for ResultClass { } } - fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> + where + Self: 'a, + { ffa? } } +impl LocalFunctor for ResultClass { + fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState>) -> IState> + where + Self: 'a, + { + match state { + Ok(IState::Pending(a)) => IState::Pending(a), + Ok(IState::Done(b)) => IState::Done(Ok(b)), + Err(e) => IState::Done(Err(e)), + } + } + + fn stuff<'a, A: 'a, T: 'a + Pure>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> + where + Self: 'a, + { + match fa { + Ok(ua) => T::fmap(Ok, ua), + Err(e) => T::pure(Err(e)), + } + } +} + impl MonadFail for ResultClass { fn fail<'a, A: 'a>(e: E) -> Self::F<'a, A> where diff --git a/src/func/classes/solo.rs b/src/func/classes/solo.rs index 188a787..a3989bc 100644 --- a/src/func/classes/solo.rs +++ b/src/func/classes/solo.rs @@ -98,3 +98,19 @@ impl Monad for SoloClass { ffa } } + +impl LocalFunctor for SoloClass { + fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState>) -> IState> + where + Self: 'a, + { + state + } + + fn stuff<'a, A: 'a, T: 'a + Pure>(fa: Self::F<'a, T::F<'a, A>>) -> T::F<'a, Self::F<'a, A>> + where + Self: 'a, + { + fa + } +}