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
102
103
104
105
106
107
108
109
pub trait FoldlIterator<E>: Iterator<Item=E> + Sized {
fn foldl<F: FnMut(E, E) -> E>(mut self, f: F) -> Option<E> {
let first = match self.next() {
None => return None,
Some(e) => e
};
Some(self.fold(first, f))
}
fn foldl_map<E1, F: FnMut(E1, E) -> E1, MapFn: FnOnce(E) -> E1>(mut self, map: MapFn, f: F) -> Option<E1> {
let first = match self.next() {
None => return None,
Some(e) => map(e)
};
Some(self.fold(first, f))
}
}
impl<It, E> FoldlIterator<E> for It where It: Iterator<Item=E> {}
#[test]
fn test_foldl() {
use std::borrow::ToOwned;
let vs = vec!["a", "b", "c"];
let vs = vs.into_iter().map(|e| e.to_owned());
assert_eq!(Some("((a, b), c)".to_owned()), vs.foldl(|a,b| format!("({}, {})", a, b)));
}
#[test]
fn test_foldl_map() {
use std::borrow::ToOwned;
let v = vec!["a", "b", "c"];
let r = v.into_iter().foldl_map(|e| e.to_owned(), |e,f| (e+", ")+f);
assert_eq!(r, Some("a, b, c".to_owned()));
}
pub trait FoldrIterator<E>: DoubleEndedIterator + Iterator<Item=E> + Sized {
fn foldr<F: FnMut(E, E) -> E>(mut self, mut f: F) -> Option<E> {
let mut last = match self.next_back() {
None => return None,
Some(e) => e
};
loop {
match self.next_back() {
None => break,
Some(e) => last = f(e, last)
}
}
Some(last)
}
}
impl<It, E> FoldrIterator<E> for It where It: DoubleEndedIterator + Iterator<Item=E> {}
#[test]
fn test_foldr() {
use std::borrow::ToOwned;
let vs = vec!["a", "b", "c"];
let vs = vs.into_iter().map(|e| e.to_owned());
assert_eq!(Some("(a, (b, c))".to_owned()), vs.foldr(|a,b| format!("({}, {})", a, b)));
}