From 18f3001e3f7fed5669b8aec080942b38e8028318 Mon Sep 17 00:00:00 2001 From: timofey Date: Sun, 12 Mar 2023 06:41:31 +0000 Subject: [PATCH] MonadFail + LazyClass --- src/func.rs | 10 +++++ src/func/classes.rs | 3 +- src/func/classes/lazyclass.rs | 74 +++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/func/classes/lazyclass.rs diff --git a/src/func.rs b/src/func.rs index 5fe83ed..8a22b8f 100644 --- a/src/func.rs +++ b/src/func.rs @@ -74,3 +74,13 @@ pub trait Monad: Applicative { 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>; +} diff --git a/src/func/classes.rs b/src/func/classes.rs index c3e60c2..6551c28 100644 --- a/src/func/classes.rs +++ b/src/func/classes.rs @@ -1,3 +1,4 @@ -pub mod optionclass; pub mod futureclass; +pub mod lazyclass; +pub mod optionclass; pub mod soloclass; diff --git a/src/func/classes/lazyclass.rs b/src/func/classes/lazyclass.rs new file mode 100644 index 0000000..ecf2ebc --- /dev/null +++ b/src/func/classes/lazyclass.rs @@ -0,0 +1,74 @@ +use crate::func::*; + +struct LazyClass; + +impl WeakFunctor for LazyClass { + type F<'a, A> = Box A>; +} + +impl Functor for LazyClass { + fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { + Box::new(|| f(fa())) + } + + fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> { + drop(fa); + Box::new(|| b) + } + + fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> { + drop(fa); + Box::new(|| ()) + } +} + +impl ApplicativeSeq for LazyClass { + 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> { + Box::new(|| ff()(fa())) + } +} + +impl ApplicativeLA2 for LazyClass { + 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> { + Box::new(|| f(fa(), fb())) + } +} + +impl Applicative for LazyClass { + fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { + Box::new(|| a) + } + + fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { + drop(fa); + fb + } + + fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A> { + drop(fb); + fa + } +} + +impl Monad for LazyClass { + 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> { + Box::new(|| 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, + { + Box::new(|| ffa()()) + } +}