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
use crate::Pure;
pub trait Bind<'a, A> {
type Target<T>;
fn bind<B, F>(self, f: F) -> Self::Target<B>
where
F: Fn(A) -> Self::Target<B> + 'a;
}
pub fn lift_m1<MA, MB, A, B, F>(f: F, a: MA) -> MB
where
F: Fn(A) -> B,
MA: for<'a> Bind<'a, A, Target<B> = MB>,
MB: Pure<B>,
{
a.bind::<B, _>(|x| MB::pure(f(x)))
}
impl<A> Bind<'_, A> for Option<A> {
type Target<T> = Option<T>;
fn bind<B, F>(self, f: F) -> Self::Target<B>
where
F: Fn(A) -> Self::Target<B>,
{
self.and_then(f)
}
}
impl<A, E> Bind<'_, A> for Result<A, E> {
type Target<T> = Result<T, E>;
fn bind<B, F>(self, f: F) -> Self::Target<B>
where
F: Fn(A) -> Self::Target<B>,
{
self.and_then(f)
}
}
#[cfg(feature = "std")]
impl<A> Bind<'_, A> for Vec<A> {
type Target<T> = Vec<T>;
fn bind<B, F>(self, f: F) -> Self::Target<B>
where
F: Fn(A) -> Self::Target<B>,
{
self.into_iter().flat_map(|v| f(v).into_iter()).collect()
}
}
#[cfg(test)]
mod test {
use crate::Bind;
#[test]
fn bind_vec() {
let v = vec![1, 2, 3];
let o = v.bind(|i| vec![i, i + 1]);
assert_eq!(vec![1, 2, 2, 3, 3, 4], o);
}
}