From feb5e5daec8f0fc46738efdb7143dc447578555b Mon Sep 17 00:00:00 2001 From: timofey Date: Tue, 23 May 2023 12:05:04 +0000 Subject: [PATCH] remove `AIterative`, extract `iterate_mut` --- src/func.rs | 51 +++++++++++---------------- src/func/classes/composition.rs | 50 -------------------------- src/func/classes/future.rs | 34 ------------------ src/func/classes/lazy.rs | 30 ---------------- src/func/classes/option.rs | 30 ---------------- src/func/classes/overload.rs | 42 ---------------------- src/func/classes/result.rs | 30 ---------------- src/func/classes/solo.rs | 30 ---------------- src/func/classes/stackless.rs | 30 ---------------- src/func/classes/tryfuture.rs | 34 ------------------ src/func/controlflow.rs | 62 ++++++--------------------------- 11 files changed, 30 insertions(+), 393 deletions(-) diff --git a/src/func.rs b/src/func.rs index 32fcb40..0ec7dc9 100644 --- a/src/func.rs +++ b/src/func.rs @@ -23,8 +23,8 @@ pub use std::ops::ControlFlow; pub use radn_derive::{CovariantFunctor, SharedFunctor}; pub use self::applicative_select::{ApplicativeSelect, Selected}; -pub use self::controlflow::{AIterative, AIterativeWrapped, Iterative, IterativeWrapped}; -use self::controlflow::{ArgumentedIterative, BindableMut, ControlFlowClass}; +use self::controlflow::{BindableMut, ControlFlowClass}; +pub use self::controlflow::{Iterative, IterativeWrapped}; /// Part of Haskell's `Functor f` responsible for having `f a`. /// @@ -180,39 +180,10 @@ pub trait Monad: Applicative { where Self: 'a; - /// Simplified, [`FnMut`] version of [`Monad::iterate_argument`]. - /// Reasoning for this method existing at all is that - /// most usecases are better modelled with [`FnMut`] - /// rather than some dedicated state type. - /// - /// Note: hypothetically, you can implement [`Monad::iterate_argument`] from [`Monad::iterate_mut`], - /// but it's highly discouraged. - 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, - { - Self::iterate_argument(a, BindableMut::new(f)) - } - - /// Kleisli category composition special case used to represent loops. /// Included for optimisation and clarity. /// Generally, [`Monad::bind`] should be enough implement it. /// See [`classes::stackless::StacklessClass::iterate`] for a generic, though less-than ideal, blanket implementation. /// On practice, you generally shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here. - 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, - { - Self::iterate(ArgumentedIterative(a, f)) - } - - /// Iteration without composition semantics of [`Monad::iterate_argument`]. fn iterate<'a, B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a; @@ -227,6 +198,24 @@ pub trait Monad: Applicative { } } +pub trait MonadExt: Monad { + /// [`FnMut`] version of [`Monad::iterate`]. + /// Reasoning for this method existing at all is that + /// most usecases are better modelled with [`FnMut`] + /// rather than some dedicated state type. + 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, + { + Self::iterate(BindableMut::new(a, f)) + } +} + +impl MonadExt for T {} + /// Part of [`MonadFail`] responsible for Haskell's `fail`. pub trait Fail: WeakFunctor { /// Equivalent of Haskell's `fail`. diff --git a/src/func/classes/composition.rs b/src/func/classes/composition.rs index 744b4a6..c99549e 100644 --- a/src/func/classes/composition.rs +++ b/src/func/classes/composition.rs @@ -119,29 +119,6 @@ impl Monad for CompositionClass { U::bind(fa, |ua| U::fmap(V::join, V::stuff::<_, U>(V::fmap(f, ua)))) } - fn iterate_mut<'a, A: 'a, B: 'a>( - a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - U::iterate_mut(a, move |a| { - let fstate = f(a); - U::fmap(|ustate| V::unstuff(ustate), fstate) - }) - } - - 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, - { - U::iterate_argument(a, AComposedIterative(f)) - } - fn iterate<'a, B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, @@ -158,33 +135,6 @@ impl Monad for CompositionClass { } } -struct AComposedIterative(F); - -impl< - 'a, - U: 'a + Monad, - V: 'a + Monad + LocalFunctor, - F: AIterative<'a, T = CompositionClass>, - > AIterative<'a> for AComposedIterative -{ - type A = F::A; - type B = ::F<'a, F::B>; - type T = U; - - fn next(self, a: Self::A) -> AIterativeWrapped<'a, Self> { - let fstate = self.0.next(a); - U::fmap( - |ustate| match V::unstuff(ustate) { - ControlFlow::Continue((next_a, next_f)) => { - ControlFlow::Continue((next_a, Self(next_f))) - } - ControlFlow::Break(b) => ControlFlow::Break(b), - }, - fstate, - ) - } -} - struct ComposedIterative(F); impl< diff --git a/src/func/classes/future.rs b/src/func/classes/future.rs index 036de27..c0ecef3 100644 --- a/src/func/classes/future.rs +++ b/src/func/classes/future.rs @@ -108,40 +108,6 @@ impl Monad for FutureClass { Box::pin(async { f(fa.await).await }) } - fn iterate_mut<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - Box::pin(async move { - loop { - match f(a).await { - ControlFlow::Continue(next_a) => a = next_a, - ControlFlow::Break(b) => return b, - }; - } - }) - } - - fn iterate_argument<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl AIterative<'a, T = Self, A = A, B = B>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - Box::pin(async move { - loop { - match f.next(a).await { - ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f), - ControlFlow::Break(b) => return b, - } - } - }) - } - fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, diff --git a/src/func/classes/lazy.rs b/src/func/classes/lazy.rs index c2ec04d..76ddc88 100644 --- a/src/func/classes/lazy.rs +++ b/src/func/classes/lazy.rs @@ -90,36 +90,6 @@ impl Monad for LazyClass { Box::new(|| f(fa())()) } - fn iterate_mut<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - Box::new(move || loop { - match f(a)() { - ControlFlow::Continue(next_a) => a = next_a, - ControlFlow::Break(b) => return b, - }; - }) - } - - fn iterate_argument<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl AIterative<'a, T = Self, A = A, B = B>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - loop { - match f.next(a)() { - ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f), - ControlFlow::Break(b) => return Self::pure(b), - } - } - } - fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, diff --git a/src/func/classes/option.rs b/src/func/classes/option.rs index 295cd31..3ac2df7 100644 --- a/src/func/classes/option.rs +++ b/src/func/classes/option.rs @@ -94,36 +94,6 @@ impl Monad for OptionClass { f(fa?) } - fn iterate_mut<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - loop { - match f(a)? { - ControlFlow::Continue(next_a) => a = next_a, - ControlFlow::Break(b) => return Self::pure(b), - }; - } - } - - fn iterate_argument<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl AIterative<'a, T = Self, A = A, B = B>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - loop { - match f.next(a)? { - ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f), - ControlFlow::Break(b) => return Self::pure(b), - } - } - } - fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, diff --git a/src/func/classes/overload.rs b/src/func/classes/overload.rs index 886a1cd..d3caad9 100644 --- a/src/func/classes/overload.rs +++ b/src/func/classes/overload.rs @@ -110,28 +110,6 @@ impl OverloadIterative { } } -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 { @@ -161,26 +139,6 @@ impl Monad for OverloadClass { 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, diff --git a/src/func/classes/result.rs b/src/func/classes/result.rs index 54d377d..b4ae158 100644 --- a/src/func/classes/result.rs +++ b/src/func/classes/result.rs @@ -115,36 +115,6 @@ impl Monad for ResultClass { f(fa?) } - fn iterate_mut<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - loop { - match f(a)? { - ControlFlow::Continue(next_a) => a = next_a, - ControlFlow::Break(b) => return Self::pure(b), - }; - } - } - - fn iterate_argument<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl AIterative<'a, T = Self, A = A, B = B>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - loop { - match f.next(a)? { - ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f), - ControlFlow::Break(b) => return Self::pure(b), - } - } - } - fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, diff --git a/src/func/classes/solo.rs b/src/func/classes/solo.rs index 4ba905a..97bf8ca 100644 --- a/src/func/classes/solo.rs +++ b/src/func/classes/solo.rs @@ -82,36 +82,6 @@ impl Monad for SoloClass { f(fa) } - fn iterate_mut<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - loop { - match f(a) { - ControlFlow::Continue(next_a) => a = next_a, - ControlFlow::Break(b) => return b, - }; - } - } - - fn iterate_argument<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl AIterative<'a, T = Self, A = A, B = B>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - loop { - match f.next(a) { - ControlFlow::Continue((new_a, new_f)) => (a, f) = (new_a, new_f), - ControlFlow::Break(b) => return b, - } - } - } - fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, diff --git a/src/func/classes/stackless.rs b/src/func/classes/stackless.rs index 5ef61ce..64a7bfe 100644 --- a/src/func/classes/stackless.rs +++ b/src/func/classes/stackless.rs @@ -226,36 +226,6 @@ impl Monad for StacklessClass { fa.bind(f) } - fn iterate_mut<'a, A: 'a, B: 'a>( - a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - Self::pure(a).bind(move |a| { - f(a).bind(|state| match state { - ControlFlow::Continue(next_a) => Self::iterate_mut(next_a, f), - ControlFlow::Break(b) => Self::pure(b), - }) - }) - } - - 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, - { - Self::pure(a).bind(move |a| { - f.next(a).bind(|state| match state { - ControlFlow::Continue((next_a, next_f)) => Self::iterate_argument(next_a, next_f), - ControlFlow::Break(b) => Self::pure(b), - }) - }) - } - fn iterate<'a, B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, diff --git a/src/func/classes/tryfuture.rs b/src/func/classes/tryfuture.rs index 342132f..177e620 100644 --- a/src/func/classes/tryfuture.rs +++ b/src/func/classes/tryfuture.rs @@ -129,40 +129,6 @@ impl Monad for TryFutureClass { Box::pin(async { f(fa.await?).await }) } - fn iterate_mut<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - Box::pin(async move { - loop { - match f(a).await? { - ControlFlow::Continue(next_a) => a = next_a, - ControlFlow::Break(b) => return Ok(b), - }; - } - }) - } - - fn iterate_argument<'a, A: 'a, B: 'a>( - mut a: A, - mut f: impl AIterative<'a, T = Self, A = A, B = B>, - ) -> Self::F<'a, B> - where - Self: 'a, - { - Box::pin(async move { - loop { - match f.next(a).await? { - ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f), - ControlFlow::Break(b) => return Ok(b), - } - } - }) - } - fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B> where Self: 'a, diff --git a/src/func/controlflow.rs b/src/func/controlflow.rs index 290944e..e3752d1 100644 --- a/src/func/controlflow.rs +++ b/src/func/controlflow.rs @@ -31,27 +31,7 @@ impl Pure for ControlFlowClass { } } -/// Next [AIterative] state, wrapped. -pub type AIterativeWrapped<'a, F> = <>::T as WeakFunctor>::F< - 'a, - ControlFlow<>::B, (>::A, F)>, ->; - -/// Value passed to [`Monad::iterate_argument`]. -/// `A` prefix meaning "with an **a**rgument" given current implementation -/// relying on the argument getting passed around. -pub trait AIterative<'a>: 'a + Sized { - /// [`ControlFlow::Continue`]. - type A: 'a; - /// [`ControlFlow::Break`]. - type B: 'a; - /// Corresponding [`WeakFunctor`]. - type T: 'a + ?Sized + WeakFunctor; - /// Get next state. - fn next(self, a: Self::A) -> AIterativeWrapped<'a, Self>; -} - -pub struct BindableMut(F, PhantomData, PhantomData, PhantomData); +pub struct BindableMut(A, F, PhantomData, PhantomData); impl< 'a, @@ -61,8 +41,8 @@ impl< F: 'a + FnMut(A) -> T::F<'a, ControlFlow>, > BindableMut { - pub fn new(f: F) -> Self { - BindableMut(f, PhantomData, PhantomData, PhantomData) + pub fn new(a: A, f: F) -> Self { + BindableMut(a, f, PhantomData, PhantomData) } } @@ -72,20 +52,21 @@ impl< A: 'a, B: 'a, F: 'a + FnMut(A) -> T::F<'a, ControlFlow>, - > AIterative<'a> for BindableMut + > Iterative<'a> for BindableMut { - type A = A; type B = B; type T = T; - fn next(mut self, a: Self::A) -> AIterativeWrapped<'a, Self> { - let fa = self.0(a); + fn next(mut self) -> IterativeWrapped<'a, Self> { + let fstate = self.1(self.0); T::fmap( move |state| match state { - ControlFlow::Continue(next_a) => ControlFlow::Continue((next_a, self)), + ControlFlow::Continue(next_a) => { + ControlFlow::Continue(BindableMut::new(next_a, self.1)) + } ControlFlow::Break(b) => ControlFlow::Break(b), }, - fa, + fstate, ) } } @@ -103,26 +84,3 @@ pub trait Iterative<'a>: 'a + Sized { /// Get next state. fn next(self) -> IterativeWrapped<'a, Self>; } - -pub struct ArgumentedIterative(pub A, pub F); - -impl<'a, A: 'a, F: AIterative<'a, A = A>> Iterative<'a> for ArgumentedIterative -where - F::T: Functor, -{ - type B = F::B; - - type T = F::T; - - fn next(self) -> IterativeWrapped<'a, Self> { - Self::T::fmap( - |state| match state { - ControlFlow::Continue((next_a, next_f)) => { - ControlFlow::Continue(ArgumentedIterative(next_a, next_f)) - } - ControlFlow::Break(b) => ControlFlow::Break(b), - }, - self.1.next(self.0), - ) - } -}