use crate::{
Applicative, CloneFunctor, Collectable, DebugFunctor, EqFunctor, Foldable, Functor, HKT, Monad,
Pure, Traversable,
};
use alloc::vec;
use alloc::vec::Vec;
pub struct VecWitness;
impl HKT for VecWitness {
type Type<T> = Vec<T>;
}
impl Pure<VecWitness> for VecWitness {
fn pure<T>(value: T) -> <VecWitness as HKT>::Type<T> {
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: Clone,
Func: 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
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>,
Func: FnMut(B, A) -> B,
{
fa.into_iter().fold(init, f)
}
}
impl Collectable<VecWitness> for VecWitness {
fn collect<T, I>(items: I) -> <VecWitness as HKT>::Type<T>
where
I: IntoIterator<Item = T>,
{
items.into_iter().collect()
}
}
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
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()
}
}
impl Traversable<VecWitness> for VecWitness {
fn sequence<A, M>(fa: alloc::vec::Vec<M::Type<A>>) -> M::Type<alloc::vec::Vec<A>>
where
M: Applicative<M> + HKT,
A: Clone,
{
let mut acc: M::Type<Vec<A>> = M::pure(Vec::new());
for m_a in fa {
acc = M::apply(
M::fmap(acc, |v: Vec<A>| {
move |a: A| {
let mut v = v.clone();
v.push(a);
v
}
}),
m_a,
);
}
acc
}
}