use crate::{HKT2Unbound, NoConstraint, Satisfies};
pub trait Morphism<P: HKT2Unbound> {
fn identity<A>() -> P::Type<A, A>
where
A: Satisfies<P::Constraint>;
fn apply<A, B>(arrow: &P::Type<A, B>, input: A) -> B
where
A: Satisfies<P::Constraint>,
B: Satisfies<P::Constraint>;
}
pub struct FnMorphism;
impl HKT2Unbound for FnMorphism {
type Constraint = NoConstraint;
type Type<A, B>
= fn(A) -> B
where
A: Satisfies<NoConstraint>,
B: Satisfies<NoConstraint>;
}
impl Morphism<FnMorphism> for FnMorphism {
#[inline]
fn identity<A>() -> <FnMorphism as HKT2Unbound>::Type<A, A>
where
A: Satisfies<NoConstraint>,
{
fn id<A>(a: A) -> A {
a
}
id::<A>
}
#[inline]
fn apply<A, B>(arrow: &<FnMorphism as HKT2Unbound>::Type<A, B>, input: A) -> B
where
A: Satisfies<NoConstraint>,
B: Satisfies<NoConstraint>,
{
(*arrow)(input)
}
}