From e670c8c6000967ac70493dc776ef0c03e92303e3 Mon Sep 17 00:00:00 2001 From: timofey <tim@ongoteam.yaconnect.com> Date: Sat, 20 May 2023 12:09:31 +0000 Subject: [PATCH] `OverloadClass` --- book-monads | 2 +- book-radn | 2 +- src/func/classes.rs | 1 + src/func/classes/overload.rs | 196 +++++++++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 src/func/classes/overload.rs 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>(T, O); + +pub trait DeriveWeakFunctor {} +impl<T: DeriveFunctor> DeriveWeakFunctor for T {} +pub trait DeriveFunctor {} +impl<T: DeriveApplicative> DeriveFunctor for T {} +pub trait DeriveApplicative {} +impl<T: DeriveMonad> DeriveApplicative for T {} +pub trait DeriveMonad {} + +impl<T: WeakFunctor, O: DeriveWeakFunctor> WeakFunctor for OverloadClass<T, O> { + type F<'a, A: 'a> = T::F<'a, A> + where + Self: 'a; +} + +impl<T: Functor, O: DeriveFunctor> Functor for OverloadClass<T, O> { + 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<T: Pure, O: DeriveApplicative> Pure for OverloadClass<T, O> { + fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> + where + Self: 'a, + { + T::pure(a) + } +} + +impl<T: ApplicativeSeq, O: DeriveApplicative> ApplicativeSeq for OverloadClass<T, O> { + 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<T: ApplicativeLA2, O: DeriveApplicative> ApplicativeLA2 for OverloadClass<T, O> { + 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<T: ApplicativeTuple, O: DeriveApplicative> ApplicativeTuple for OverloadClass<T, O> { + 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<T: Applicative, O: DeriveApplicative> Applicative for OverloadClass<T, O> { + 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, O>(F, PhantomData<O>); + +impl<F, O> OverloadIterative<F, O> { + fn new(f: F) -> Self { + Self(f, PhantomData) + } +} + +impl<'a, T: 'a + Monad, O: 'a + DeriveMonad, F: AIterative<'a, T = OverloadClass<T, O>>> + AIterative<'a> for OverloadIterative<F, O> +{ + 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<T, O>>> + Iterative<'a> for OverloadIterative<F, O> +{ + 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<T: Monad, O: DeriveMonad> Monad for OverloadClass<T, O> { + 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<B, A>>, + ) -> 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) + } +}