use crate::{Applicative, CoMonad, Foldable, Functor, HKT, Monad, NoConstraint, Pure, Satisfies};
use alloc::boxed::Box;
pub struct BoxWitness;
impl HKT for BoxWitness {
type Constraint = NoConstraint;
type Type<T> = Box<T>;
}
impl Functor<BoxWitness> for BoxWitness {
fn fmap<A, B, Func>(
m_a: <BoxWitness as HKT>::Type<A>,
mut f: Func,
) -> <BoxWitness as HKT>::Type<B>
where
A: Satisfies<NoConstraint>,
B: Satisfies<NoConstraint>,
Func: FnMut(A) -> B,
{
Box::new(f(*m_a))
}
}
impl Pure<BoxWitness> for BoxWitness {
fn pure<T>(value: T) -> <BoxWitness as HKT>::Type<T>
where
T: Satisfies<NoConstraint>,
{
Box::new(value)
}
}
impl Applicative<BoxWitness> for BoxWitness {
fn apply<A, B, Func>(
mut f_ab: <BoxWitness as HKT>::Type<Func>,
f_a: <BoxWitness as HKT>::Type<A>,
) -> <BoxWitness as HKT>::Type<B>
where
A: Satisfies<NoConstraint> + Clone,
B: Satisfies<NoConstraint>,
Func: Satisfies<NoConstraint> + FnMut(A) -> B,
{
Box::new((*f_ab)(*f_a))
}
}
impl Foldable<BoxWitness> for BoxWitness {
fn fold<A, B, Func>(fa: Box<A>, init: B, mut f: Func) -> B
where
Func: FnMut(B, A) -> B,
{
f(init, *fa)
}
}
impl Monad<BoxWitness> for BoxWitness {
fn bind<A, B, Func>(
m_a: <BoxWitness as HKT>::Type<A>,
mut f: Func,
) -> <BoxWitness as HKT>::Type<B>
where
A: Satisfies<NoConstraint>,
B: Satisfies<NoConstraint>,
Func: FnMut(A) -> <BoxWitness as HKT>::Type<B>,
{
f(*m_a)
}
}
impl CoMonad<BoxWitness> for BoxWitness {
fn extract<A>(fa: &<Self as HKT>::Type<A>) -> A
where
A: Satisfies<NoConstraint> + Clone,
{
*fa.clone()
}
fn extend<A, B, Func>(fa: &<Self as HKT>::Type<A>, mut f: Func) -> <Self as HKT>::Type<B>
where
A: Satisfies<NoConstraint> + Clone,
B: Satisfies<NoConstraint>,
Func: FnMut(&<Self as HKT>::Type<A>) -> B,
{
Box::new(f(fa))
}
}