use crate::{Applicative, Foldable, Functor, HKT, Monad, NoConstraint, Pure, Satisfies};
use alloc::vec;
use alloc::vec::Vec;
pub struct VecWitness;
impl HKT for VecWitness {
type Constraint = NoConstraint;
type Type<T> = Vec<T>;
}
impl Pure<VecWitness> for VecWitness {
fn pure<T>(value: T) -> <VecWitness as HKT>::Type<T>
where
T: Satisfies<NoConstraint>,
{
vec![value]
}
}
impl Applicative<VecWitness> for VecWitness {
fn apply<A, B, Func>(
f_ab: <VecWitness as HKT>::Type<Func>,
f_a: <VecWitness as HKT>::Type<A>,
) -> <VecWitness as HKT>::Type<B>
where
A: Satisfies<NoConstraint> + Clone,
B: Satisfies<NoConstraint>,
Func: Satisfies<NoConstraint> + FnMut(A) -> B,
{
f_ab.into_iter()
.flat_map(|mut f_val| {
f_a.iter()
.map(move |a_val| f_val(a_val.clone()))
.collect::<Vec<B>>()
})
.collect()
}
}
impl Functor<VecWitness> for VecWitness {
fn fmap<A, B, Func>(m_a: <VecWitness as HKT>::Type<A>, f: Func) -> <VecWitness as HKT>::Type<B>
where
A: Satisfies<NoConstraint>,
B: Satisfies<NoConstraint>,
Func: FnMut(A) -> B,
{
m_a.into_iter().map(f).collect()
}
}
impl Foldable<VecWitness> for VecWitness {
fn fold<A, B, Func>(fa: <VecWitness as HKT>::Type<A>, init: B, f: Func) -> B
where
<VecWitness as HKT>::Type<A>: IntoIterator<Item = A>,
A: Satisfies<NoConstraint>,
Func: FnMut(B, A) -> B,
{
fa.into_iter().fold(init, f)
}
}
impl Monad<VecWitness> for VecWitness {
fn bind<A, B, Func>(m_a: <VecWitness as HKT>::Type<A>, f: Func) -> <VecWitness as HKT>::Type<B>
where
A: Satisfies<NoConstraint>,
B: Satisfies<NoConstraint>,
Func: FnMut(A) -> <VecWitness as HKT>::Type<B>,
{
m_a.into_iter().flat_map(f).collect()
}
}