1use crate::Pure;
2
3pub trait Bind<'a, A> {
15 type Target<T>;
16 fn bind<B, F>(self, f: F) -> Self::Target<B>
17 where
18 F: Fn(A) -> Self::Target<B> + 'a;
19}
20
21pub fn lift_m1<MA, MB, A, B, F>(f: F, a: MA) -> MB
25where
26 F: Fn(A) -> B,
27 MA: for<'a> Bind<'a, A, Target<B> = MB>,
28 MB: Pure<B>,
29{
30 a.bind::<B, _>(|x| MB::pure(f(x)))
31}
32
33impl<A> Bind<'_, A> for Option<A> {
34 type Target<T> = Option<T>;
35
36 fn bind<B, F>(self, f: F) -> Self::Target<B>
37 where
38 F: Fn(A) -> Self::Target<B>,
39 {
40 self.and_then(f)
41 }
42}
43
44impl<A, E> Bind<'_, A> for Result<A, E> {
45 type Target<T> = Result<T, E>;
46
47 fn bind<B, F>(self, f: F) -> Self::Target<B>
48 where
49 F: Fn(A) -> Self::Target<B>,
50 {
51 self.and_then(f)
52 }
53}
54
55#[cfg(feature = "std")]
56impl<A> Bind<'_, A> for Vec<A> {
57 type Target<T> = Vec<T>;
58
59 fn bind<B, F>(self, f: F) -> Self::Target<B>
60 where
61 F: Fn(A) -> Self::Target<B>,
62 {
63 self.into_iter().flat_map(|v| f(v).into_iter()).collect()
64 }
65}
66
67#[cfg(test)]
68mod test {
69 use crate::Bind;
70
71 #[test]
72 fn bind_vec() {
73 let v = vec![1, 2, 3];
74 let o = v.bind(|i| vec![i, i + 1]);
75 assert_eq!(vec![1, 2, 2, 3, 3, 4], o);
76 }
77}