From 6048c5504b766e53d23cd55358a435bc80fb7e87 Mon Sep 17 00:00:00 2001 From: timofey Date: Tue, 23 May 2023 12:42:08 +0000 Subject: [PATCH] `MonadFailAny::join` --- src/func.rs | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/func.rs b/src/func.rs index f7f3a55..4769470 100644 --- a/src/func.rs +++ b/src/func.rs @@ -273,6 +273,18 @@ pub trait MonadFailAny { /// Associated infallible [`Monad`]. type T: Monad; + fn unstuff<'a, A: 'a, E: 'a>( + wa: as WeakFunctor>::F<'a, A>, + ) -> ::F<'a, Result> + where + Self: 'a; + + fn stuff<'a, A: 'a, E: 'a>( + fa: ::F<'a, Result>, + ) -> as WeakFunctor>::F<'a, A> + where + Self: 'a; + /// Equivalent of [`Result::map_err`]. fn map_err<'a, A: 'a, E0: 'a, E1: 'a>( wa: as WeakFunctor>::F<'a, A>, @@ -284,6 +296,7 @@ pub trait MonadFailAny { Self::bind_err(wa, |e0| Self::fail(f(e0))) } + /// Equivalent of `catch`/`except`. To inject errors on success, see [`MonadFailAny::bind`]. 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>, @@ -297,6 +310,11 @@ pub trait MonadFailAny { }) } + /// Bind the result, an equivalent of `catch`/`except` with ability to "raise" extra errors + /// on success too, unlike [`MonadFailAny::bind_err`]. + /// + /// Note: Reasonably it is expected to lack fail semantics for the underlying result. + /// Therefore the default implementation descends into the non-fail monad [`MonadFailAny::T`]. fn bind<'a, A: 'a, B: 'a, E0: 'a, E1: 'a>( wa: as WeakFunctor>::F<'a, A>, f: impl 'a + FnOnce(Result) -> as WeakFunctor>::F<'a, B>, @@ -309,6 +327,22 @@ pub trait MonadFailAny { })) } + /// Equivalent of [`Monad::join`], flattening the errors. + /// + /// Note: default implementation doesn't depend on [`Monad::join`]. + fn join<'a, A: 'a, E0: 'a, E1: 'a>( + wwa: as WeakFunctor>::F<'a, as WeakFunctor>::F<'a, A>>, + ) -> > as WeakFunctor>::F<'a, A> + where + Self: 'a, + { + Self::bind(wwa, |result| match result { + Ok(wa) => Self::map_err(wa, Ok), + Err(e1) => Self::fail(Err(e1)), + }) + } + + /// Lift the error. fn rotate_out<'a, A: 'a, E0: 'a, E1: 'a>( wa: as WeakFunctor>::F<'a, Result>, ) -> > as WeakFunctor>::F<'a, A> @@ -320,17 +354,6 @@ pub trait MonadFailAny { Err(e) => Self::fail(Ok(e)), }) } - fn unstuff<'a, A: 'a, E: 'a>( - wa: as WeakFunctor>::F<'a, A>, - ) -> ::F<'a, Result> - where - Self: 'a; - - fn stuff<'a, A: 'a, E: 'a>( - fa: ::F<'a, Result>, - ) -> as WeakFunctor>::F<'a, A> - where - Self: 'a; } pub trait MonadFailAnyExt: MonadFailAny {