1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crate::Foldable::*;
impl <A, B> FoldableB<B> for Vec<A> {
fn fold_right<F>(&self, z: B, f: F) -> B where F: Fn(&Self::A, B) -> B {
let mut r: B = z;
for x in self.iter().rev() {
r = f(x, r);
}
r
}
fn fold_left<F>(&self, z: B, f: F) -> B where F: Fn(B, &Self::A) -> B {
self.iter().fold(z, f)
}
}
impl <'r,A: 'r> FoldableA<'r, A> for Vec<A> {
fn fold<F>(&'r self, z: A, f: F) -> A where F: FnMut(A, &A) -> A {
self.iter().fold(z, f)
}
fn all<F>(&'r self, f: F) -> bool where F: Fn(&A) -> bool {
self.iter().all(f)
}
fn any<F>(&'r self, f: F) -> bool where F: Fn(&A) -> bool {
self.iter().any(f)
}
fn filter<F>(&'r self, f: F) -> Self::M where F: Fn(&A) -> bool {
self.iter().filter(|a| f(a)).collect()
}
fn find<F>(&'r self, f: F) -> Option<&A> where F: Fn(&A) -> bool {
self.iter().find(|a| f(a))
}
fn is_empty(&'r self) -> bool { self.is_empty() }
}
impl <'r,A: 'r> FoldableS<'r, A> for Option<A> {
fn fold<F>(&'r self, z: A, f: F) -> A where F: Fn(&A) -> A {
match self {
Some(v) => f(v),
None => z,
}
}
fn all<F>(&'r self, f: F) -> bool where F: Fn(&A) -> bool {
self.iter().all(f)
}
fn any<F>(&'r self, f: F) -> bool where F: Fn(&A) -> bool {
self.iter().any(f)
}
fn filter<F>(&'r self, f: F) -> Self::M where F: Fn(&A) -> bool {
self.iter().find(|a| f(a))
}
fn find<F>(&'r self, f: F) -> Option<&A> where F: Fn(&A) -> bool {
self.iter().find(|a| f(a))
}
fn is_empty(&'r self) -> bool { self.is_none() }
}
#[cfg(test)]
mod test {
use crate::Foldable::*;
#[test]
fn vec_filter() {
let v1 = vec![1,2,3,4];
assert_eq!(vec![&2,&4], v1.filter(|&a| a%2==0))
}
#[test]
fn option_filter_negative() {
let v1 = Option::Some(7);
assert_eq!(Option::None, v1.filter(|&a| a > 10));
}
#[test]
fn option_filter_positive() {
let v1 = Option::Some(7);
assert_eq!(Option::Some(7), v1.filter(|&a| a < 10));
}
#[test]
fn vec_filter_then_fold_left() {
let v1 = vec![1,2,3,4];
assert_eq!(6, v1.filter(|&a| a%2==0).fold_left(0, |b,&a| a + b));
}
#[test]
fn vec_filter_then_fold_right() {
let v1 = vec![1,2,3,4];
assert_eq!(6, v1.filter(|&a| a%2==0).fold_right(0, |&a,b| a + b));
}
#[test]
fn vec_concat() {
let v1 = vec![(0.1f64 * 1000f64),(0.2f64 * 1000f64)];
assert_eq!(0.3f64, (v1.concat() / 1000f64));
}
}