From 3d0e96e22b1e8359b3ecb657fd9c1b07e93e267a Mon Sep 17 00:00:00 2001 From: timofey Date: Thu, 25 May 2023 17:19:23 +0000 Subject: [PATCH] select_map --- src/func.rs | 4 +++- src/func/applicative_select.rs | 15 +++++++++++++++ src/func/speculative.rs | 10 ++++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/func.rs b/src/func.rs index e107078..1ec06f1 100644 --- a/src/func.rs +++ b/src/func.rs @@ -23,7 +23,9 @@ pub use std::ops::ControlFlow; pub use radn_derive::{CovariantFunctor, SharedFunctor}; -pub use self::applicative_select::{ApplicativeSelect, Selected, SelectedWrapped}; +pub use self::applicative_select::{ + ApplicativeSelect, ApplicativeSelectExt, 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 d5de629..98beced 100644 --- a/src/func/applicative_select.rs +++ b/src/func/applicative_select.rs @@ -18,3 +18,18 @@ pub trait ApplicativeSelect: Functor { Self::fmap(|a| Selected::A(a, fb), fa) } } + +pub trait ApplicativeSelectExt: ApplicativeSelect { + fn select_map<'a, A: 'a, B: 'a, C: 'a>( + f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C, + fa: Self::F<'a, A>, + fb: Self::F<'a, B>, + ) -> Self::F<'a, C> + where + Self: 'a, + { + Self::fmap(f, Self::select(fa, fb)) + } +} + +impl ApplicativeSelectExt for T {} diff --git a/src/func/speculative.rs b/src/func/speculative.rs index ec5d269..cafe044 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, - ::fmap( + Self::T::select_map( |selected| match selected { Selected::A(a, fwb) => Self::_speculative_a_fwb(a, fwb), Selected::B(fa, Ok(wb)) => { @@ -62,7 +62,8 @@ pub trait SpeculativeFail: MonadFailAny { } Selected::B(_, Err(e1)) => Self::fail(Err(e1)), }, - ::select(Self::unstuff(wa), fwb), + Self::unstuff(wa), + fwb, ), ), )) @@ -90,14 +91,15 @@ pub trait SpeculativeFail: MonadFailAny { { Self::stuff(::join(::fmap( Self::unstuff, - ::fmap( + Self::T::select_map( |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)), }, - ::select(Self::unstuff(wwa), Self::unstuff(wwb)), + Self::unstuff(wwa), + Self::unstuff(wwb), ), ))) }