From 00c5239ce55b293ebedd2d801b19560fa4dc4b6c Mon Sep 17 00:00:00 2001 From: timofey Date: Sun, 12 Mar 2023 20:47:49 +0000 Subject: [PATCH] ResultClass + better lifetimes + less matches --- src/func/classes.rs | 1 + src/func/classes/futureclass.rs | 2 - src/func/classes/lazyclass.rs | 2 - src/func/classes/optionclass.rs | 37 +++++-------------- src/func/classes/resultclass.rs | 65 +++++++++++++++++++++++++++++++++ src/func/classes/soloclass.rs | 2 - 6 files changed, 75 insertions(+), 34 deletions(-) create mode 100644 src/func/classes/resultclass.rs diff --git a/src/func/classes.rs b/src/func/classes.rs index 6551c28..65a4526 100644 --- a/src/func/classes.rs +++ b/src/func/classes.rs @@ -1,4 +1,5 @@ pub mod futureclass; pub mod lazyclass; pub mod optionclass; +pub mod resultclass; pub mod soloclass; diff --git a/src/func/classes/futureclass.rs b/src/func/classes/futureclass.rs index bc8d351..ef88273 100644 --- a/src/func/classes/futureclass.rs +++ b/src/func/classes/futureclass.rs @@ -71,8 +71,6 @@ impl Monad for FutureClass { } fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> - where - Self::F<'a, A>: 'a, { Box::pin(async { ffa.await.await }) } diff --git a/src/func/classes/lazyclass.rs b/src/func/classes/lazyclass.rs index ecf2ebc..a412899 100644 --- a/src/func/classes/lazyclass.rs +++ b/src/func/classes/lazyclass.rs @@ -66,8 +66,6 @@ impl Monad for LazyClass { } fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> - where - Self::F<'a, A>: 'a, { Box::new(|| ffa()()) } diff --git a/src/func/classes/optionclass.rs b/src/func/classes/optionclass.rs index 4e12b64..c246b70 100644 --- a/src/func/classes/optionclass.rs +++ b/src/func/classes/optionclass.rs @@ -21,10 +21,7 @@ impl ApplicativeSeq for OptionClass { ff: Self::F<'a, F>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> { - match (ff, fa) { - (Some(f), Some(a)) => Some(f(a)), - _ => None, - } + Self::pure(ff?(fa?)) } } @@ -34,10 +31,7 @@ impl ApplicativeLA2 for OptionClass { fa: Self::F<'a, A>, fb: Self::F<'a, B>, ) -> Self::F<'a, C> { - match (fa, fb) { - (Some(a), Some(b)) => Some(f(a, b)), - _ => None, - } + Self::pure(f(fa?, fb?)) } } @@ -47,17 +41,13 @@ impl Applicative for OptionClass { } fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { - match fa { - Some(_) => fb, - None => None, - } + fa?; + fb } fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { - match fb { - Some(_) => fa, - None => None, - } + fb?; + fa } } @@ -66,20 +56,11 @@ impl Monad for OptionClass { fa: Self::F<'a, A>, f: F, ) -> Self::F<'a, B> { - match fa { - Some(a) => f(a), - None => None, - } + f(fa?) } - fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> - where - Self::F<'a, A>: 'a, - { - match ffa { - Some(Some(a)) => Some(a), - _ => None, - } + fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + ffa? } } diff --git a/src/func/classes/resultclass.rs b/src/func/classes/resultclass.rs new file mode 100644 index 0000000..e59715f --- /dev/null +++ b/src/func/classes/resultclass.rs @@ -0,0 +1,65 @@ +use crate::func::*; + +pub struct ResultClass(E); + +impl WeakFunctor for ResultClass { + type F<'a, A> = Result; +} + +impl Functor for ResultClass { + fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { + fa.map(f) + } + + fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + fa.map(|_| b) + } +} + +impl ApplicativeSeq for ResultClass { + fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( + ff: Self::F<'a, F>, + fa: Self::F<'a, A>, + ) -> Self::F<'a, B> { + Self::pure(ff?(fa?)) + } +} + +impl ApplicativeLA2 for ResultClass { + fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( + f: F, + fa: Self::F<'a, A>, + fb: Self::F<'a, B>, + ) -> Self::F<'a, C> { + Self::pure(f(fa?, fb?)) + } +} + +impl Applicative for ResultClass { + fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { + Ok(a) + } + + fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + fa?; + fb + } + + fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + fb?; + fa + } +} + +impl Monad for ResultClass { + fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( + fa: Self::F<'a, A>, + f: F, + ) -> Self::F<'a, B> { + f(fa?) + } + + fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> { + ffa? + } +} diff --git a/src/func/classes/soloclass.rs b/src/func/classes/soloclass.rs index 1075477..f04d3e0 100644 --- a/src/func/classes/soloclass.rs +++ b/src/func/classes/soloclass.rs @@ -65,8 +65,6 @@ impl Monad for SoloClass { } fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> - where - Self::F<'a, A>: 'a, { ffa }