use super::{fail::*, *}; pub type WrapC<'a, A, Ctx> = Wrap<'a, A, >::T>; pub trait FunctorContext<'a>: 'a + Send { type T: WeakFunctor<'a>; } pub trait MonadContext<'a>: FunctorContext<'a, T = Self::_Tm> { type _Tm: Monad<'a>; } pub trait FunctorContextExt<'a>: FunctorContext<'a> { fn fmap( fa: WrapC<'a, A, Self>, f: impl 'a + Send + FnOnce(A) -> B, ) -> WrapC<'a, B, Self> where Self::T: Functor<'a>, { ::fmap(fa, f) } fn pure(a: A) -> WrapC<'a, A, Self> where Self::T: Pure<'a>, { ::pure(a) } fn bind( fa: WrapC<'a, A, Self>, f: impl 'a + Send + FnOnce(A) -> WrapC<'a, B, Self>, ) -> WrapC<'a, B, Self> where Self::T: Monad<'a>, { ::bind(fa, f) } fn fail(e: E) -> WrapC<'a, A, Self> where Self::T: Fail<'a, E>, { >::fail(e) } } impl<'a, Ctx: FunctorContext<'a>> FunctorContextExt<'a> for Ctx {} pub trait FallibleCtx<'a>: FunctorContext<'a> { /// Type to allow improved support for [`Result`] evaluation. /// This is important for async applications stopping early. type Fallible: MonadFailAny<'a, T = Self::T>; } /// Preferred monad for fallible uses. pub type FallibleMonad<'a, Ctx, E> = <>::Fallible as MonadFailAny<'a>>::W; /// Preferred [Wrap]ped [Result]. pub type FallibleWrapped<'a, Ctx, A, E> = Wrap<'a, A, FallibleMonad<'a, Ctx, E>>; /// Extention trait for simpler conversion between [`FunctorContext::T`] and [`FallibleCtx::Fallible`]. /// /// this is the preferred way to switch between [WrapC] and [FallibleWrapped]. pub trait FallibleCtxExt<'a>: FallibleCtx<'a> { /// Convert a fallible wrapped into a wrapped result. fn unstuff( wa: FallibleWrapped<'a, Self, A, E>, ) -> WrapC<'a, Result, Self> { Self::Fallible::unstuff(wa) } /// Convert a wrapped result into a fallible wrapped. fn stuff( fa: WrapC<'a, Result, Self>, ) -> FallibleWrapped<'a, Self, A, E> { Self::Fallible::stuff(fa) } } impl<'a, Ctx: FallibleCtx<'a>> FallibleCtxExt<'a> for Ctx {}