use fail::*; use crate::func::*; type Frwa<'a, A, E0, E1, Fallible> = Wrap<'a, Result, E1>, >::T>; type Wwa<'a, A, E0, E1, Fallible> = WrapE<'a, WrapE<'a, A, E0, Fallible>, E1, Fallible>; trait SpeculativeFailImpl<'a>: MonadFailAny<'a> { fn _speculative_a_wb( a: A, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), Result, Self> { Self::map_err( as Functor>::fmap(wb, |b| (a, b)), Ok) } fn _speculative_ra_wb( ra: Result, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), Result, Self> { match ra { Ok(a) => Self::_speculative_a_wb(a, wb), Err(e0) => Self::fail(Ok(e0)), } } fn _speculative_ra_rwb( ra: Result, rwb: Result, E1>, ) -> WrapE<'a, (A, B), Result, Self> { match rwb { Ok(wb) => Self::_speculative_ra_wb(ra, wb), Err(e1) => Self::fail(Err(e1)), } } fn _speculative_ra_frwb( ra: Result, frwb: Frwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { Self::stuff(::bind(frwb, |rwb| { Self::unstuff(Self::_speculative_ra_rwb(ra, rwb)) })) } fn _speculative_fra_wb( fra: Wrap<'a, Result, Self::T>, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), E0, Self> { as ApplicativeTuple>::tuple((Self::stuff(fra), wb)) } fn _speculative_wa_frwb( wa: WrapE<'a, A, E0, Self>, frwb: Frwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { Self::stuff(<::T as Monad>::join( <::T as Functor>::fmap( Self::T::select_map(Self::unstuff(wa), frwb, |selected| match selected { Selected::A(ra, frwb) => Self::_speculative_ra_frwb(ra, frwb), Selected::B(fra, Ok(wb)) => { Self::map_err(Self::_speculative_fra_wb(fra, wb), Ok) } Selected::B(_, Err(e1)) => Self::fail(Err(e1)), }), Self::unstuff, ), )) } fn _speculative_frwa_wb( frwa: Frwa<'a, A, E0, E1, Self>, wb: WrapE<'a, B, E0, Self>, ) -> WrapE<'a, (A, B), Result, Self> { > as Functor>::fmap( Self::_speculative_wa_frwb(wb, frwa), |(b, a)| (a, b), ) } fn _speculative( wwa: Wwa<'a, A, E0, E1, Self>, wwb: Wwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { Self::stuff(::join(::fmap( Self::T::select_map( Self::unstuff(wwa), Self::unstuff(wwb), |selected| match selected { Selected::A(Ok(wa), frwb) => Self::_speculative_wa_frwb(wa, frwb), Selected::A(Err(e1), _) => Self::fail(Err(e1)), Selected::B(frwa, Ok(wb)) => Self::_speculative_frwa_wb(frwa, wb), Selected::B(_, Err(e1)) => Self::fail(Err(e1)), }, ), Self::unstuff, ))) } } pub trait SpeculativeFail<'a>: MonadFailAny<'a> { fn speculative( wwa: Wwa<'a, A, E0, E1, Self>, wwb: Wwa<'a, B, E0, E1, Self>, ) -> WrapE<'a, (A, B), Result, Self> { Self::_speculative(wwa, wwb) } } impl<'a, Fallible: ?Sized + MonadFailAny<'a>> SpeculativeFailImpl<'a> for Fallible {} impl<'a, Fallible: ?Sized + MonadFailAny<'a>> SpeculativeFail<'a> for Fallible {}