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