rust_fp_categories/
bind.rs1use std::rc::Rc;
2
3pub trait Bind {
4 type Elm;
5 type M<B>;
6
7 fn bind<B, F>(self, f: F) -> Self::M<B>
8 where
9 F: Fn(&Self::Elm) -> Self::M<B>;
10}
11
12macro_rules! bind_numeric_impl {
13 ($($t:ty)*) => ($(
14 impl Bind for $t {
15 type Elm = $t;
16 type M<U> = U;
17
18 fn bind<B, F>(self, f: F) -> Self::M<B>
19 where
20 F: Fn(&Self::Elm) -> Self::M<B>,
21 {
22 f(&self)
23 }
24 }
25 )*)
26}
27
28bind_numeric_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
29
30impl<A> Bind for Rc<A> {
31 type Elm = A;
32 type M<U> = Rc<U>;
33
34 fn bind<B, F>(self, f: F) -> Self::M<B>
35 where
36 F: FnOnce(&Self::Elm) -> Self::M<B>,
37 {
38 f(&self)
39 }
40}
41
42impl<A> Bind for Box<A> {
43 type Elm = A;
44 type M<U> = Box<U>;
45
46 fn bind<B, F>(self, f: F) -> Self::M<B>
47 where
48 F: FnOnce(&Self::Elm) -> Self::M<B>,
49 {
50 f(&self)
51 }
52}
53
54impl<A> Bind for Option<A> {
57 type Elm = A;
58 type M<U> = Option<U>;
59
60 fn bind<B, F>(self, f: F) -> Self::M<B>
61 where
62 F: FnOnce(&Self::Elm) -> Self::M<B>,
63 {
64 self.and_then(|e| f(&e))
65 }
66}
67
68impl<A, E: Clone> Bind for Result<A, E> {
69 type Elm = A;
70 type M<U> = Result<U, E>;
71
72 fn bind<B, F>(self, f: F) -> Self::M<B>
73 where
74 F: FnOnce(&Self::Elm) -> Self::M<B>,
75 {
76 self.and_then(|e| f(&e))
77 }
78}
79
80impl<A> Bind for Vec<A> {
81 type Elm = A;
82 type M<U> = Vec<U>;
83
84 fn bind<B, F>(self, f: F) -> Self::M<B>
85 where
86 F: Fn(&Self::Elm) -> Self::M<B>,
87 {
88 self.iter().flat_map(f).collect()
89 }
90}