From bd361833b557d951d0683e5dd99242c75976eb01 Mon Sep 17 00:00:00 2001 From: timofey Date: Wed, 26 Apr 2023 03:37:06 +0000 Subject: [PATCH] bind_err/rotate_out --- src/func.rs | 19 +++++++++++++ src/func/classes/result.rs | 58 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/func.rs b/src/func.rs index 52d81f4..9fd2fbb 100644 --- a/src/func.rs +++ b/src/func.rs @@ -247,6 +247,25 @@ pub trait MonadFailAny { ) -> as WeakFunctor>::F<'a, A> where Self: 'a; + + fn bind_err<'a, A: 'a, E0: 'a, E1: 'a>( + wa: as WeakFunctor>::F<'a, A>, + f: impl 'a + FnOnce(E0) -> as WeakFunctor>::F<'a, A>, + ) -> as WeakFunctor>::F<'a, A> + where + Self: 'a; + + fn rotate_out<'a, A: 'a, E0: 'a, E1: 'a>( + wa: as WeakFunctor>::F<'a, Result>, + ) -> > as WeakFunctor>::F<'a, A> + where + Self: 'a, + { + > as Monad>::bind(Self::map_err(wa, Err), |fa| match fa { + Ok(a) => > as Pure>::pure(a), + Err(e) => > as MonadFail>>::fail(Ok(e)), + }) + } } /// Represents a (collection of) [Monad]\(s), diff --git a/src/func/classes/result.rs b/src/func/classes/result.rs index 8d63020..ef3caa1 100644 --- a/src/func/classes/result.rs +++ b/src/func/classes/result.rs @@ -161,6 +161,19 @@ impl MonadFail for ResultClass { pub struct ResultFailAny; +trait ResultExt<'a, A: 'a, E0: 'a>: 'a { + fn bind_err(self, f: impl 'a + FnOnce(E0) -> Result) -> Result; +} + +impl<'a, A: 'a, E0: 'a> ResultExt<'a, A, E0> for Result { + fn bind_err(self, f: impl 'a + FnOnce(E0) -> Result) -> Result { + match self { + Ok(a) => Ok(a), + Err(e) => f(e), + } + } +} + impl MonadFailAny for ResultFailAny { type W = ResultClass; @@ -173,6 +186,29 @@ impl MonadFailAny for ResultFailAny { { wa.map_err(f) } + + fn bind_err<'a, A: 'a, E0: 'a, E1: 'a>( + wa: as WeakFunctor>::F<'a, A>, + f: impl 'a + FnOnce(E0) -> as WeakFunctor>::F<'a, A>, + ) -> as WeakFunctor>::F<'a, A> + where + Self: 'a, + { + wa.bind_err(f) + } + + fn rotate_out<'a, A: 'a, E0: 'a, E1: 'a>( + wa: as WeakFunctor>::F<'a, Result>, + ) -> > as WeakFunctor>::F<'a, A> + where + Self: 'a, + { + match wa { + Ok(Ok(a)) => Ok(a), + Ok(Err(e)) => Err(Ok(e)), + Err(e) => Err(Err(e)), + } + } } impl MonadFailOver for ResultFailAny { @@ -211,6 +247,28 @@ impl MonadFailAny for ResultFailOver { { T::fmap(|a| a.map_err(f), wa) } + + fn bind_err<'a, A: 'a, E0: 'a, E1: 'a>( + wa: as WeakFunctor>::F<'a, A>, + f: impl 'a + FnOnce(E0) -> as WeakFunctor>::F<'a, A>, + ) -> as WeakFunctor>::F<'a, A> + where + Self: 'a, + { + T::bind(wa, |a| match a { + Ok(a) => T::pure(Ok(a)), + Err(e) => f(e), + }) + } + + fn rotate_out<'a, A: 'a, E0: 'a, E1: 'a>( + wa: as WeakFunctor>::F<'a, Result>, + ) -> > as WeakFunctor>::F<'a, A> + where + Self: 'a, + { + T::fmap(::rotate_out, wa) + } } impl MonadFailOver for ResultFailOver {