diff --git a/src/func/classes/overload.rs b/src/func/classes/overload.rs index d74aef6..238958b 100644 --- a/src/func/classes/overload.rs +++ b/src/func/classes/overload.rs @@ -194,3 +194,89 @@ impl Monad for OverloadClass { T::join(ffa) } } + +struct DeriveFail(Ex); + +impl DeriveMonad for DeriveFail {} + +impl>> Fail for OverloadClass> { + fn fail<'a, A: 'a>(e: E) -> Self::F<'a, A> + where + Self: 'a, + E: 'a, + { + T::fail(Ok(e)) + } +} + +struct DeriveFailAny(Ex, Fallible); + +impl MonadFailAny for DeriveFailAny { + type W = OverloadClass>, DeriveFail>; + + fn map_err<'a, A: 'a, E0: 'a, E1: 'a>( + wa: as WeakFunctor>::F<'a, A>, + f: impl 'a + FnOnce(E0) -> E1, + ) -> as WeakFunctor>::F<'a, A> + where + Self: 'a, + { + Fallible::map_err(wa, |err| err.map(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, + { + Fallible::bind_err(wa, |err| match err { + Ok(e0) => f(e0), + Err(ex) => Fallible::fail(Err(ex)), + }) + } + + 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>, + ) -> as WeakFunctor>::F<'a, B> + where + Self: 'a, + { + Fallible::bind(wa, |result| match result { + Ok(a) => f(Ok(a)), + Err(Ok(e0)) => f(Err(e0)), + Err(Err(ex)) => Fallible::fail(Err(ex)), + }) + } +} + +impl MonadFailOver> for DeriveFailAny { + fn unstuff<'a, A: 'a, E: 'a>( + wa: as WeakFunctor>::F<'a, A>, + ) -> as WeakFunctor>::F<'a, Result> + where + Self: 'a, + Fallible::W: 'a, + { + Fallible::bind_err( as Functor>::fmap(Ok, wa), |err| match err { + Ok(e) => Fallible::pure(Err(e)), + Err(ex) => Fallible::fail(ex), + }) + } + + fn stuff<'a, A: 'a, E: 'a>( + fa: as WeakFunctor>::F<'a, Result>, + ) -> as WeakFunctor>::F<'a, A> + where + Self: 'a, + Fallible::W: 'a, + { + Fallible::bind(fa, |result| match result { + Ok(Ok(a)) => Fallible::pure(a), + Ok(Err(e)) => Fallible::fail(Ok(e)), + Err(ex) => Fallible::fail(Err(ex)), + }) + } +}