naan/impls/
vec.rs

1use std_alloc::vec;
2use std_alloc::vec::Vec;
3
4use crate::prelude::*;
5
6/// Vec Kinds
7pub mod hkt {
8  use super::*;
9
10  /// [`std::vec::Vec`] lifted to an HKT1
11  ///
12  /// (Kind `Type -> Type`)
13  pub struct Vec;
14  impl HKT1 for Vec {
15    type T<A> = ::std_alloc::vec::Vec<A>;
16  }
17}
18
19impl<A> Functor<hkt::Vec, A> for Vec<A> {
20  fn fmap<AB, B>(self, f: AB) -> Vec<B>
21    where AB: F1<A, Ret = B>
22  {
23    self.into_iter().map(|a| f.call(a)).collect()
24  }
25}
26
27impl<AB> Apply<hkt::Vec, AB> for Vec<AB> {
28  fn apply_with<A, B, Cloner>(self,
29                              a: <hkt::Vec as HKT1>::T<A>,
30                              cloner: Cloner)
31                              -> <hkt::Vec as HKT1>::T<B>
32    where AB: F1<A, Ret = B>,
33          Cloner: for<'a> F1<&'a A, Ret = A>
34  {
35    self.into_iter()
36        .flat_map(move |f| a.iter().map(|a| f.call(cloner.call(a))).collect::<Vec<B>>())
37        .collect()
38  }
39}
40
41impl<A> Applicative<hkt::Vec, A> for Vec<A> {
42  fn pure(a: A) -> Vec<A> {
43    vec![a]
44  }
45}
46
47impl<A> Alt<hkt::Vec, A> for Vec<A> {
48  fn alt(mut self, mut b: Self) -> Self {
49    Vec::append(&mut self, &mut b);
50    self
51  }
52}
53deriving!(impl Plus<hkt::Vec, A> for Vec<A> {..Default});
54
55deriving!(impl<A> Semigroup for Vec<A> {..Alt});
56deriving!(impl<A> Monoid for Vec<A> {..Default});
57
58impl<A> FoldableIndexed<hkt::Vec, usize, A> for Vec<A> {
59  fn foldl_idx<B, BAB>(self, f: BAB, b: B) -> B
60    where BAB: F3<B, usize, A, Ret = B>
61  {
62    self.into_iter()
63        .enumerate()
64        .fold(b, |b, (ix, a)| f.call(b, ix, a))
65  }
66
67  /// CHECK: Enumerate yields _indexes_ (not the number of iterations) when
68  /// going backwards in a double ended iterator
69  ///
70  /// ```
71  /// use naan::prelude::*;
72  ///
73  /// vec![0, 1, 2].foldl_idx(|(), ix, val| assert_eq!(ix, val), ());
74  /// vec![0, 1, 2].foldr_idx(|ix, val, ()| assert_eq!(ix, val), ());
75  /// ```
76  fn foldr_idx<B, ABB>(self, f: ABB, b: B) -> B
77    where ABB: F3<usize, A, B, Ret = B>
78  {
79    self.into_iter()
80        .enumerate()
81        .rfold(b, |b, (ix, a)| f.call(ix, a, b))
82  }
83
84  fn foldl_idx_ref<'a, B, BAB>(&'a self, f: BAB, b: B) -> B
85    where BAB: F3<B, usize, &'a A, Ret = B>,
86          A: 'a
87  {
88    self.iter()
89        .enumerate()
90        .fold(b, |b, (ix, a)| f.call(b, ix, a))
91  }
92
93  fn foldr_idx_ref<'a, B, ABB>(&'a self, f: ABB, b: B) -> B
94    where ABB: F3<usize, &'a A, B, Ret = B>,
95          A: 'a
96  {
97    self.iter()
98        .enumerate()
99        .rfold(b, |b, (ix, a)| f.call(ix, a, b))
100  }
101}
102deriving!(impl Foldable<hkt::Vec, A> for Vec<A> {..FoldableIndexed});
103
104#[allow(non_camel_case_types)]
105type append<T> = fn(T, Vec<T>) -> Vec<T>;
106
107/// curried [`fn@append`] waiting for both arguments
108#[allow(non_camel_case_types)]
109pub type append0<T> = curry2::Curry2<append<T>, Nothing<T>, Nothing<Vec<T>>, Vec<T>>;
110
111/// curried [`fn@append`] that has a T and is waiting for the Vec to push it to
112#[allow(non_camel_case_types)]
113pub type append1<T> = curry2::Curry2<append<T>, Just<T>, Nothing<Vec<T>>, Vec<T>>;
114
115/// Append an element to a vec
116pub fn append<T>(t: T, mut v: Vec<T>) -> Vec<T> {
117  v.push(t);
118  v
119}
120
121impl<A, B> Traversable<hkt::Vec, A, B, append1<B>> for Vec<A> {
122  fn traversem1<Ap, AtoApOfB>(self, f: AtoApOfB) -> Ap::T<Vec<B>>
123    where Ap: HKT1,
124          Self: Foldable<hkt::Vec, A>,
125          Ap::T<B>: Applicative<Ap, B> + ApplyOnce<Ap, B>,
126          Ap::T<append1<B>>: Applicative<Ap, append1<B>> + ApplyOnce<Ap, append1<B>>,
127          Ap::T<Vec<B>>: Applicative<Ap, Vec<B>> + ApplyOnce<Ap, Vec<B>>,
128          AtoApOfB: F1<A, Ret = Ap::T<B>>,
129          hkt::Vec: HKT1<T<A> = Self>
130  {
131    self.foldl(|ap, a| f.call(a).fmap((append as append<B>).curry()).apply1(ap),
132               Ap::T::pure(vec![]))
133  }
134
135  fn traversemm<Ap, AtoApOfB>(self, f: AtoApOfB) -> Ap::T<Vec<B>>
136    where Ap: HKT1,
137          Self: Foldable<hkt::Vec, A>,
138          B: Clone,
139          Ap::T<B>: Applicative<Ap, B>,
140          Ap::T<append1<B>>: Applicative<Ap, append1<B>>,
141          Ap::T<Vec<B>>: Applicative<Ap, Vec<B>>,
142          AtoApOfB: F1<A, Ret = Ap::T<B>>,
143          hkt::Vec: HKT1<T<A> = Self>
144  {
145    self.foldl(|ap, a| f.call(a).fmap((append as append<B>).curry()).apply(ap),
146               Ap::T::pure(vec![]))
147  }
148}
149
150impl<A> Monad<hkt::Vec, A> for Vec<A> {
151  fn bind<B, AMB>(self, f: AMB) -> Vec<B>
152    where AMB: F1<A, Ret = Vec<B>>
153  {
154    let mut out = Vec::<B>::new();
155
156    for i in self {
157      Vec::append(&mut out, &mut f.call(i));
158    }
159
160    out
161  }
162}