diff --git a/src/func.rs b/src/func.rs index e29e1da..d1292d9 100644 --- a/src/func.rs +++ b/src/func.rs @@ -23,7 +23,7 @@ pub use std::ops::ControlFlow; pub use radn_derive::{CovariantFunctor, SharedFunctor}; -pub use self::applicative_select::{ApplicativeSelect, Selected}; +pub use self::applicative_select::{ApplicativeSelect, Selected, SelectedWrapped}; use self::controlflow::{BindableMut, ControlFlowInstance}; pub use self::controlflow::{Iterative, IterativeWrapped}; #[cfg(doc)] diff --git a/src/func/applicative_select.rs b/src/func/applicative_select.rs index d5b0a1d..c270e30 100644 --- a/src/func/applicative_select.rs +++ b/src/func/applicative_select.rs @@ -5,15 +5,16 @@ pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + 'a + WeakFunctor> { B(T::F<'a, A>, B), } +pub type SelectedWrapped<'a, A, B, T> = ::F<'a, Selected<'a, A, B, T>>; + pub trait ApplicativeSelect: Functor { - fn select<'a, A: 'a, B: 'a, C: 'a>( - f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, + fn select<'a, A: 'a, B: 'a>( fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> + ) -> SelectedWrapped<'a, A, B, Self> where Self: 'a, { - Self::fmap(|a| f(Selected::A(a, fb)), fa) + Self::fmap(|a| Selected::A(a, fb), fa) } } diff --git a/src/func/instances/composition.rs b/src/func/instances/composition.rs index 32b9f3f..c513def 100644 --- a/src/func/instances/composition.rs +++ b/src/func/instances/composition.rs @@ -73,21 +73,19 @@ impl ApplicativeTuple for CompositionI } impl ApplicativeSelect for CompositionInstance { - fn select<'a, A: 'a, B: 'a, C: 'a>( - f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, + fn select<'a, A: 'a, B: 'a>( fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> + ) -> SelectedWrapped<'a, A, B, Self> where Self: 'a, { - U::select( + U::fmap( |selected| match selected { - Selected::A(ua, fb) => V::fmap(|a| f(Selected::A(a, fb)), ua), - Selected::B(fa, ub) => V::fmap(|b| f(Selected::B(fa, b)), ub), + Selected::A(ua, fb) => V::fmap(|a| Selected::A(a, fb), ua), + Selected::B(fa, ub) => V::fmap(|b| Selected::B(fa, b), ub), }, - fa, - fb, + U::select(fa, fb), ) } } diff --git a/src/func/instances/future.rs b/src/func/instances/future.rs index 1086a6d..b554f4f 100644 --- a/src/func/instances/future.rs +++ b/src/func/instances/future.rs @@ -73,18 +73,17 @@ impl ApplicativeTuple for FutureInstance { } impl ApplicativeSelect for FutureInstance { - fn select<'a, A: 'a, B: 'a, C: 'a>( - f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, + fn select<'a, A: 'a, B: 'a>( fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> + ) -> SelectedWrapped<'a, A, B, Self> where Self: 'a, { Box::pin(async { match select(fa, fb).await { - Either::Left((a, fb)) => f(Selected::A(a, fb)), - Either::Right((b, fa)) => f(Selected::B(fa, b)), + Either::Left((a, fb)) => Selected::A(a, fb), + Either::Right((b, fa)) => Selected::B(fa, b), } }) } diff --git a/src/func/instances/tryfuture.rs b/src/func/instances/tryfuture.rs index d2a91e9..7228f7b 100644 --- a/src/func/instances/tryfuture.rs +++ b/src/func/instances/tryfuture.rs @@ -83,18 +83,17 @@ impl ApplicativeTuple for TryFutureInstance { } impl ApplicativeSelect for TryFutureInstance { - fn select<'a, A: 'a, B: 'a, C: 'a>( - f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, + fn select<'a, A: 'a, B: 'a>( fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> + ) -> SelectedWrapped<'a, A, B, Self> where Self: 'a, { Box::pin(async { match try_select(fa, fb).await { - Ok(Either::Left((a, fb))) => Ok(f(Selected::A(a, fb))), - Ok(Either::Right((b, fa))) => Ok(f(Selected::B(fa, b))), + Ok(Either::Left((a, fb))) => Ok(Selected::A(a, fb)), + Ok(Either::Right((b, fa))) => Ok(Selected::B(fa, b)), Err(Either::Left((e, _))) => Err(e), Err(Either::Right((e, _))) => Err(e), } diff --git a/src/func/speculative.rs b/src/func/speculative.rs index 39fd30e..4c26d89 100644 --- a/src/func/speculative.rs +++ b/src/func/speculative.rs @@ -54,7 +54,7 @@ pub trait SpeculativeFail: MonadFailAny { Self::stuff(<::T as Monad>::join( <::T as Functor>::fmap( Self::unstuff, - ::select( + ::fmap( |selected| match selected { Selected::A(a, fwb) => Self::_speculative_a_fwb(a, fwb), Selected::B(fa, Ok(wb)) => { @@ -62,8 +62,7 @@ pub trait SpeculativeFail: MonadFailAny { } Selected::B(_, Err(e1)) => Self::fail(Err(e1)), }, - Self::unstuff(wa), - fwb, + ::select(Self::unstuff(wa), fwb), ), ), )) @@ -91,15 +90,14 @@ pub trait SpeculativeFail: MonadFailAny { { Self::stuff(::join(::fmap( Self::unstuff, - ::select( + ::fmap( |selected| match selected { Selected::A(Ok(wa), fwb) => Self::_speculative_wa_fwb(wa, fwb), Selected::A(Err(e1), _) => Self::fail(Err(e1)), Selected::B(fwa, Ok(wb)) => Self::_speculative_fwa_wb(fwa, wb), Selected::B(_, Err(e1)) => Self::fail(Err(e1)), }, - Self::unstuff(wwa), - Self::unstuff(wwb), + ::select(Self::unstuff(wwa), Self::unstuff(wwb)), ), ))) }