152 lines
4.6 KiB
Rust
152 lines
4.6 KiB
Rust
use crate::func::*;
|
|
|
|
pub struct CompositionInstance<U, V>(U, V);
|
|
|
|
impl<'a, U: WeakFunctorA<'a>, V: WeakFunctorA<'a>> WeakFunctorA<'a> for CompositionInstance<U, V> {
|
|
type Fa<A: 'a> = U::Fa<V::Fa<A>>;
|
|
}
|
|
|
|
impl<'a, U: Functor<'a>, V: Functor<'a>> Functor<'a> for CompositionInstance<U, V> {
|
|
fn fmap<A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::Fa<A>) -> Self::Fa<B> {
|
|
U::fmap(|ua| V::fmap(f, ua), fa)
|
|
}
|
|
|
|
fn replace<A: 'a, B: 'a>(fa: Self::Fa<A>, b: B) -> Self::Fa<B> {
|
|
U::fmap(|ua| V::replace(ua, b), fa)
|
|
}
|
|
|
|
fn void<A: 'a>(fa: Self::Fa<A>) -> Self::Fa<()> {
|
|
U::fmap(|ua| V::void(ua), fa)
|
|
}
|
|
}
|
|
|
|
impl<'a, U: Pure<'a>, V: Pure<'a>> Pure<'a> for CompositionInstance<U, V> {
|
|
fn pure<A: 'a>(a: A) -> Self::Fa<A> {
|
|
U::pure(V::pure(a))
|
|
}
|
|
}
|
|
|
|
impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeSeq<'a>> ApplicativeSeq<'a>
|
|
for CompositionInstance<U, V>
|
|
{
|
|
fn seq<A: 'a, B: 'a>(ff: Self::Fa<impl 'a + FnOnce(A) -> B>, fa: Self::Fa<A>) -> Self::Fa<B> {
|
|
U::la2(|uf, ua| V::seq(uf, ua), ff, fa)
|
|
}
|
|
}
|
|
|
|
impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeLA2<'a>> ApplicativeLA2<'a>
|
|
for CompositionInstance<U, V>
|
|
{
|
|
fn la2<A: 'a, B: 'a, C: 'a>(
|
|
f: impl 'a + FnOnce(A, B) -> C,
|
|
fa: Self::Fa<A>,
|
|
fb: Self::Fa<B>,
|
|
) -> Self::Fa<C> {
|
|
U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb)
|
|
}
|
|
}
|
|
|
|
impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a>
|
|
for CompositionInstance<U, V>
|
|
{
|
|
fn tuple<A: 'a, B: 'a>(fab: (Self::Fa<A>, Self::Fa<B>)) -> Self::Fa<(A, B)> {
|
|
U::fmap(V::tuple, U::tuple(fab))
|
|
}
|
|
}
|
|
|
|
impl<'a, U: ApplicativeSelect<'a>, V: Functor<'a>> ApplicativeSelect<'a>
|
|
for CompositionInstance<U, V>
|
|
{
|
|
fn select<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> SelectedWrapped<'a, A, B, Self> {
|
|
U::fmap(
|
|
|selected| match selected {
|
|
Selected::A(ua, fb) => V::fmap(|a| Selected::A(a, fb), ua),
|
|
Selected::B(fa, ub) => V::fmap(|b| Selected::B(fa, b), ub),
|
|
},
|
|
U::select(fa, fb),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'a, U: Applicative<'a>, V: Applicative<'a>> Applicative<'a> for CompositionInstance<U, V> {
|
|
fn discard_first<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<B> {
|
|
U::la2(|ua, ub| V::discard_first(ua, ub), fa, fb)
|
|
}
|
|
|
|
fn discard_second<A: 'a, B: 'a>(fa: Self::Fa<A>, fb: Self::Fa<B>) -> Self::Fa<A> {
|
|
U::la2(|ua, ub| V::discard_second(ua, ub), fa, fb)
|
|
}
|
|
}
|
|
|
|
impl<'a, U: Monad<'a>, V: Monad<'a> + LocalFunctor<'a>> Monad<'a> for CompositionInstance<U, V> {
|
|
fn bind<A: 'a, B: 'a>(fa: Self::Fa<A>, f: impl 'a + FnOnce(A) -> Self::Fa<B>) -> Self::Fa<B> {
|
|
U::bind(fa, |ua| U::fmap(V::join, V::stuff::<_, U>(V::fmap(f, ua))))
|
|
}
|
|
|
|
fn iterate<B: 'a>(f: impl Iterative<'a, T = Self, B = B>) -> Self::Fa<B> {
|
|
U::iterate(ComposedIterative(f))
|
|
}
|
|
|
|
fn join<A: 'a>(ffa: Self::Fa<Self::Fa<A>>) -> Self::Fa<A> {
|
|
U::join(U::fmap(|ufa| U::fmap(V::join, V::stuff::<_, U>(ufa)), ffa))
|
|
}
|
|
}
|
|
|
|
struct ComposedIterative<F>(F);
|
|
|
|
impl<
|
|
'a,
|
|
U: Monad<'a>,
|
|
V: Monad<'a> + LocalFunctor<'a>,
|
|
F: Iterative<'a, T = CompositionInstance<U, V>>,
|
|
> Iterative<'a> for ComposedIterative<F>
|
|
{
|
|
type B = Wrap<'a, F::B, V>;
|
|
type T = U;
|
|
|
|
fn next(self) -> IterativeWrapped<'a, Self> {
|
|
let fstate = self.0.next();
|
|
U::fmap(
|
|
|ustate| match V::unstuff(ustate) {
|
|
ControlFlow::Continue(next_f) => ControlFlow::Continue(Self(next_f)),
|
|
ControlFlow::Break(b) => ControlFlow::Break(b),
|
|
},
|
|
fstate,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'a, E: 'a, U: Monad<'a>, V: Fail<'a, E> + LocalFunctor<'a>> Fail<'a, E>
|
|
for CompositionInstance<U, V>
|
|
{
|
|
fn fail<A: 'a>(e: E) -> Self::Fa<A> {
|
|
U::pure(V::fail(e))
|
|
}
|
|
}
|
|
|
|
impl<'a, U: LocalFunctor<'a> + Functor<'a>, V: LocalFunctor<'a>> LocalFunctor<'a>
|
|
for CompositionInstance<U, V>
|
|
{
|
|
fn unstuff<A: 'a, B: 'a>(state: Self::Fa<ControlFlow<B, A>>) -> ControlFlow<Self::Fa<B>, A> {
|
|
U::unstuff(U::fmap(V::unstuff, state))
|
|
}
|
|
|
|
fn stuff<A: 'a, T: Pure<'a>>(fa: Self::Fa<T::Fa<A>>) -> T::Fa<Self::Fa<A>> {
|
|
U::stuff::<_, T>(U::fmap(V::stuff::<_, T>, fa))
|
|
}
|
|
}
|
|
|
|
impl<'a, U: SharedFunctorA<'a> + Functor<'a>, V: SharedFunctorA<'a>> SharedFunctorA<'a>
|
|
for CompositionInstance<U, V>
|
|
{
|
|
type SharedA<A: 'a + Clone> = U::SharedA<V::SharedA<A>>;
|
|
|
|
fn share<A: 'a + Clone>(fa: Self::Fa<A>) -> Self::SharedA<A> {
|
|
U::share(U::fmap(V::share, fa))
|
|
}
|
|
|
|
fn unshare<A: 'a + Clone>(sa: Self::SharedA<A>) -> Self::Fa<A> {
|
|
U::fmap(V::unshare, U::unshare(sa))
|
|
}
|
|
}
|