diff --git a/book-monads b/book-monads index a4e6c75..02ac841 160000 --- a/book-monads +++ b/book-monads @@ -1 +1 @@ -Subproject commit a4e6c75644ce6fe6635680f144df148e0ae6f794 +Subproject commit 02ac841b9787c2f9c52b8ed306ba6edb5067a4e0 diff --git a/book-radn b/book-radn index bb44e06..309258a 160000 --- a/book-radn +++ b/book-radn @@ -1 +1 @@ -Subproject commit bb44e06dea5b3a00585066063be00c4b3a976f70 +Subproject commit 309258abbea7ca7a8ba1d4d254ec26f001a76d77 diff --git a/src/func/classes.rs b/src/func/classes.rs index 14678ff..e283e65 100644 --- a/src/func/classes.rs +++ b/src/func/classes.rs @@ -24,6 +24,7 @@ pub mod effect; pub mod future; pub mod lazy; pub mod option; +pub mod overload; pub mod result; pub mod solo; pub mod stackless; diff --git a/src/func/classes/overload.rs b/src/func/classes/overload.rs new file mode 100644 index 0000000..964854c --- /dev/null +++ b/src/func/classes/overload.rs @@ -0,0 +1,196 @@ +use std::marker::PhantomData; + +use crate::func::*; + +pub struct OverloadClass(T, O); + +pub trait DeriveWeakFunctor {} +impl DeriveWeakFunctor for T {} +pub trait DeriveFunctor {} +impl DeriveFunctor for T {} +pub trait DeriveApplicative {} +impl DeriveApplicative for T {} +pub trait DeriveMonad {} + +impl WeakFunctor for OverloadClass { + type F<'a, A: 'a> = T::F<'a, A> + where + Self: 'a; +} + +impl Functor for OverloadClass { + 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, + { + T::fmap(f, fa) + } + + fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> + where + Self: 'a, + { + T::replace(fa, b) + } + + fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> + where + Self: 'a, + { + T::void(fa) + } +} + +impl Pure for OverloadClass { + fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> + where + Self: 'a, + { + T::pure(a) + } +} + +impl ApplicativeSeq for OverloadClass { + 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, + { + T::seq(ff, fa) + } +} + +impl ApplicativeLA2 for OverloadClass { + 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, + { + T::la2(f, fa, fb) + } +} + +impl ApplicativeTuple for OverloadClass { + fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> + where + Self: 'a, + { + T::tuple(fab) + } +} + +impl Applicative for OverloadClass { + 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, + { + T::discard_first(fa, 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, + { + T::discard_second(fa, fb) + } +} + +struct OverloadIterative(F, PhantomData); + +impl OverloadIterative { + fn new(f: F) -> Self { + Self(f, PhantomData) + } +} + +impl<'a, T: 'a + Monad, O: 'a + DeriveMonad, F: AIterative<'a, T = OverloadClass>> + AIterative<'a> for OverloadIterative +{ + type A = F::A; + + type B = F::B; + + type T = T; + + fn next(self, a: Self::A) -> AIterativeWrapped<'a, Self> { + T::fmap( + |state| match state { + ControlFlow::Continue((next_a, next_f)) => { + ControlFlow::Continue((next_a, Self::new(next_f))) + } + ControlFlow::Break(b) => ControlFlow::Break(b), + }, + self.0.next(a), + ) + } +} + +impl<'a, T: 'a + Monad, O: 'a + DeriveMonad, F: Iterative<'a, T = OverloadClass>> + Iterative<'a> for OverloadIterative +{ + type B = F::B; + + type T = T; + + fn next(self) -> IterativeWrapped<'a, Self> { + T::fmap( + |state| match state { + ControlFlow::Continue(next_f) => ControlFlow::Continue(Self::new(next_f)), + ControlFlow::Break(b) => ControlFlow::Break(b), + }, + self.0.next(), + ) + } +} + +impl Monad for OverloadClass { + 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, + { + T::bind(fa, f) + } + + fn iterate_mut<'a, A: 'a, B: 'a>( + a: A, + f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, + ) -> Self::F<'a, B> + where + Self: 'a, + { + T::iterate_mut(a, f) + } + + fn iterate_argument<'a, A: 'a, B: 'a>( + a: A, + f: impl AIterative<'a, T = Self, A = A, B = B>, + ) -> Self::F<'a, B> + where + Self: 'a, + { + T::iterate_argument(a, OverloadIterative::new(f)) + } + + fn iterate<'a, B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> + where + Self: 'a, + { + T::iterate(OverloadIterative::new(f)) + } + + 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, + { + T::join(ffa) + } +}