use std_alloc::vec;
use std_alloc::vec::Vec;
use crate::prelude::*;
pub mod hkt {
use super::*;
pub struct Vec;
impl HKT1 for Vec {
type T<A> = ::std_alloc::vec::Vec<A>;
}
}
impl<A> Functor<hkt::Vec, A> for Vec<A> {
fn fmap<AB, B>(self, f: AB) -> Vec<B>
where AB: F1<A, Ret = B>
{
self.into_iter().map(|a| f.call(a)).collect()
}
}
impl<AB> Apply<hkt::Vec, AB> for Vec<AB> {
fn apply_with<A, B, Cloner>(self,
a: <hkt::Vec as HKT1>::T<A>,
cloner: Cloner)
-> <hkt::Vec as HKT1>::T<B>
where AB: F1<A, Ret = B>,
Cloner: for<'a> F1<&'a A, Ret = A>
{
self.into_iter()
.flat_map(move |f| a.iter().map(|a| f.call(cloner.call(a))).collect::<Vec<B>>())
.collect()
}
}
impl<A> Applicative<hkt::Vec, A> for Vec<A> {
fn pure(a: A) -> Vec<A> {
vec![a]
}
}
impl<A> Alt<hkt::Vec, A> for Vec<A> {
fn alt(mut self, mut b: Self) -> Self {
Vec::append(&mut self, &mut b);
self
}
}
deriving!(impl Plus<hkt::Vec, A> for Vec<A> {..Default});
deriving!(impl<A> Semigroup for Vec<A> {..Alt});
deriving!(impl<A> Monoid for Vec<A> {..Default});
impl<A> FoldableIndexed<hkt::Vec, usize, A> for Vec<A> {
fn foldl_idx<B, BAB>(self, f: BAB, b: B) -> B
where BAB: F3<B, usize, A, Ret = B>
{
self.into_iter()
.enumerate()
.fold(b, |b, (ix, a)| f.call(b, ix, a))
}
fn foldr_idx<B, ABB>(self, f: ABB, b: B) -> B
where ABB: F3<usize, A, B, Ret = B>
{
self.into_iter()
.enumerate()
.rfold(b, |b, (ix, a)| f.call(ix, a, b))
}
fn foldl_idx_ref<'a, B, BAB>(&'a self, f: BAB, b: B) -> B
where BAB: F3<B, usize, &'a A, Ret = B>,
A: 'a
{
self.iter()
.enumerate()
.fold(b, |b, (ix, a)| f.call(b, ix, a))
}
fn foldr_idx_ref<'a, B, ABB>(&'a self, f: ABB, b: B) -> B
where ABB: F3<usize, &'a A, B, Ret = B>,
A: 'a
{
self.iter()
.enumerate()
.rfold(b, |b, (ix, a)| f.call(ix, a, b))
}
}
deriving!(impl Foldable<hkt::Vec, A> for Vec<A> {..FoldableIndexed});
#[allow(non_camel_case_types)]
type append<T> = fn(T, Vec<T>) -> Vec<T>;
#[allow(non_camel_case_types)]
pub type append0<T> = curry2::Curry2<append<T>, Nothing<T>, Nothing<Vec<T>>, Vec<T>>;
#[allow(non_camel_case_types)]
pub type append1<T> = curry2::Curry2<append<T>, Just<T>, Nothing<Vec<T>>, Vec<T>>;
pub fn append<T>(t: T, mut v: Vec<T>) -> Vec<T> {
v.push(t);
v
}
impl<A, B> Traversable<hkt::Vec, A, B, append1<B>> for Vec<A> {
fn traversem1<Ap, AtoApOfB>(self, f: AtoApOfB) -> Ap::T<Vec<B>>
where Ap: HKT1,
Self: Foldable<hkt::Vec, A>,
Ap::T<B>: Applicative<Ap, B> + ApplyOnce<Ap, B>,
Ap::T<append1<B>>: Applicative<Ap, append1<B>> + ApplyOnce<Ap, append1<B>>,
Ap::T<Vec<B>>: Applicative<Ap, Vec<B>> + ApplyOnce<Ap, Vec<B>>,
AtoApOfB: F1<A, Ret = Ap::T<B>>,
hkt::Vec: HKT1<T<A> = Self>
{
self.foldl(|ap, a| f.call(a).fmap((append as append<B>).curry()).apply1(ap),
Ap::T::pure(vec![]))
}
fn traversemm<Ap, AtoApOfB>(self, f: AtoApOfB) -> Ap::T<Vec<B>>
where Ap: HKT1,
Self: Foldable<hkt::Vec, A>,
B: Clone,
Ap::T<B>: Applicative<Ap, B>,
Ap::T<append1<B>>: Applicative<Ap, append1<B>>,
Ap::T<Vec<B>>: Applicative<Ap, Vec<B>>,
AtoApOfB: F1<A, Ret = Ap::T<B>>,
hkt::Vec: HKT1<T<A> = Self>
{
self.foldl(|ap, a| f.call(a).fmap((append as append<B>).curry()).apply(ap),
Ap::T::pure(vec![]))
}
}
impl<A> Monad<hkt::Vec, A> for Vec<A> {
fn bind<B, AMB>(self, f: AMB) -> Vec<B>
where AMB: F1<A, Ret = Vec<B>>
{
let mut out = Vec::<B>::new();
for i in self {
Vec::append(&mut out, &mut f.call(i));
}
out
}
}