113 lines
4.0 KiB
Rust
113 lines
4.0 KiB
Rust
use fail::*;
|
|
|
|
use crate::func::*;
|
|
|
|
type Frwa<'a, A, E0, E1, Fallible> =
|
|
Wrap<'a, Result<WrapE<'a, A, E0, Fallible>, E1>, <Fallible as MonadFailAny<'a>>::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, B: 'a, E0: 'a, E1: 'a>(
|
|
a: A,
|
|
wb: WrapE<'a, B, E0, Self>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
|
|
Self::map_err(<Self::W<E0> as Functor>::fmap(wb, |b| (a, b)), Ok)
|
|
}
|
|
|
|
fn _speculative_ra_wb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
|
|
ra: Result<A, E0>,
|
|
wb: WrapE<'a, B, E0, Self>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
|
|
match ra {
|
|
Ok(a) => Self::_speculative_a_wb(a, wb),
|
|
Err(e0) => Self::fail(Ok(e0)),
|
|
}
|
|
}
|
|
|
|
fn _speculative_ra_rwb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
|
|
ra: Result<A, E0>,
|
|
rwb: Result<WrapE<'a, B, E0, Self>, E1>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
|
|
match rwb {
|
|
Ok(wb) => Self::_speculative_ra_wb(ra, wb),
|
|
Err(e1) => Self::fail(Err(e1)),
|
|
}
|
|
}
|
|
|
|
fn _speculative_ra_frwb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
|
|
ra: Result<A, E0>,
|
|
frwb: Frwa<'a, B, E0, E1, Self>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
|
|
Self::stuff(<Self::T as Monad>::bind(frwb, |rwb| {
|
|
Self::unstuff(Self::_speculative_ra_rwb(ra, rwb))
|
|
}))
|
|
}
|
|
|
|
fn _speculative_fra_wb<A: 'a, B: 'a, E0: 'a>(
|
|
fra: Wrap<'a, Result<A, E0>, Self::T>,
|
|
wb: WrapE<'a, B, E0, Self>,
|
|
) -> WrapE<'a, (A, B), E0, Self> {
|
|
<Self::W<E0> as ApplicativeTuple>::tuple((Self::stuff(fra), wb))
|
|
}
|
|
|
|
fn _speculative_wa_frwb<A: 'a, B: 'a, E0: 'a, E1: 'a>(
|
|
wa: WrapE<'a, A, E0, Self>,
|
|
frwb: Frwa<'a, B, E0, E1, Self>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
|
|
Self::stuff(<<Self as MonadFailAny>::T as Monad>::join(
|
|
<<Self as MonadFailAny>::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<A: 'a, B: 'a, E0: 'a, E1: 'a>(
|
|
frwa: Frwa<'a, A, E0, E1, Self>,
|
|
wb: WrapE<'a, B, E0, Self>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
|
|
<Self::W<Result<E0, E1>> as Functor>::fmap(
|
|
Self::_speculative_wa_frwb(wb, frwa),
|
|
|(b, a)| (a, b),
|
|
)
|
|
}
|
|
|
|
fn _speculative<A: 'a, B: 'a, E0: 'a, E1: 'a>(
|
|
wwa: Wwa<'a, A, E0, E1, Self>,
|
|
wwb: Wwa<'a, B, E0, E1, Self>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, Self> {
|
|
Self::stuff(<Self::T as Monad>::join(<Self::T as Functor>::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<A: 'a, B: 'a, E0: 'a, E1: 'a>(
|
|
wwa: Wwa<'a, A, E0, E1, Self>,
|
|
wwb: Wwa<'a, B, E0, E1, Self>,
|
|
) -> WrapE<'a, (A, B), Result<E0, E1>, 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 {}
|