use crate::{
Applicative, CloneFunctor, CoMonad, DebugFunctor, EqFunctor, 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 EqFunctor for BoxWitness {
fn eq_type<T: PartialEq>(a: &<Self as HKT>::Type<T>, b: &<Self as HKT>::Type<T>) -> bool {
a == b
}
}
impl DebugFunctor for BoxWitness {
fn fmt_type<T: core::fmt::Debug>(
fa: &<Self as HKT>::Type<T>,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
core::fmt::Debug::fmt(fa, f)
}
}
impl CloneFunctor for BoxWitness {
fn clone_type<T: Clone>(fa: &<Self as HKT>::Type<T>) -> <Self as HKT>::Type<T> {
fa.clone()
}
}
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))
}
}