metatrait 0.0.0-alpha.1

RPITIT Monads
Documentation
use either::Either;

use crate::{
    traits::{
        either::IntoEither,
        is::{Is, IsExt},
    },
    Free, Impl, Trait,
};

use super::functor::*;

pub trait MapFn<In: ?Sized + Trait> {
    type Out: ?Sized + Trait;
    fn run(self, _: impl Impl<In>) -> impl Impl<Self::Out>;
}

impl<F: FnOnce(In) -> Out, In, Out> MapFn<Is<In>> for F {
    type Out = Is<Out>;

    fn run(self, x: impl Impl<Is<In>>) -> impl Impl<Self::Out> {
        self(x.into_that())
    }
}

pub trait MapFn2<In0: ?Sized + Trait, In1: ?Sized + Trait> {
    type Out: ?Sized + Trait;
    fn run(self, _: impl Impl<In0>, _: impl Impl<In1>) -> impl Impl<Self::Out>;
}

pub trait TraitFn: Sized {
    type Out: ?Sized + Trait;
}

pub trait SelectFn<In0: ?Sized + Trait, In1: ?Sized + Trait>: TraitFn {
    type Tr0: ?Sized + Trait;
    type Tr1: ?Sized + Trait;

    fn run0(self, _: impl Impl<In0>) -> Either<impl Impl<Self::Out>, impl Impl<Self::Tr0>>;
    fn run1(self, _: impl Impl<In1>) -> Either<impl Impl<Self::Out>, impl Impl<Self::Tr1>>;
    fn run01(_: impl Impl<Self::Tr0>, _: impl Impl<In1>) -> impl Impl<Self::Out>;
    fn run10(_: impl Impl<Self::Tr1>, _: impl Impl<In0>) -> impl Impl<Self::Out>;
}

pub trait IterateFn<Wr: ?Sized + Wrap>: TraitFn {
    fn run(self) -> impl Impl<Wr::Wrap<IntoEither<Self, Self::Out>>>;
}

pub trait IterateFnExt<Wr: ?Sized + Iterate>: IterateFn<Wr> {
    fn run_iterate(self) -> impl Impl<Wr::Wrap<Self::Out>> {
        Wr::iterate(self)
    }
}

impl<Wr: ?Sized + Iterate, F: IterateFn<Wr>> IterateFnExt<Wr> for F {}

pub trait InspectFn<In: ?Sized + Trait, Wr: ?Sized + Wrap> {
    type Out: ?Sized + Free;
    fn run(self, _: &mut impl Impl<In>) -> impl Impl<Wr::Wrap<Self::Out>>;
}