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
#[macro_export]
macro_rules! hado {
(ret ( $ty:ty ) $expr:expr) => {
$crate::Monad::< $ty >::ret($expr)
};
(ret $expr:expr) => {
$crate::Monad::ret($expr)
};
(ign <- $expr:expr; $($rest:tt)*) => {
$crate::Monad::bind($expr, |_| hado!($($rest)*))
};
(mut $ident:ident <- $expr:expr; $($rest:tt)*) => {
$crate::Monad::bind($expr, |mut $ident| hado!($($rest)*))
};
($ident:ident <- $expr:expr; $($rest:tt)*) => {
$crate::Monad::bind($expr, |$ident| hado!($($rest)*))
};
($stmt:stmt; $($rest:tt)*) => {
{ $stmt ; hado!($($rest)*) }
};
($expr:expr) => {
$expr
}
}
pub trait Monad<O> {
type Inner;
fn bind<F>(t: Self, f: F) -> O where F: FnMut(Self::Inner) -> O ;
fn ret(Self::Inner) -> Self;
}
impl<T, O> Monad<Option<O>> for Option<T> {
type Inner = T;
fn bind<F>(t: Option<T>, mut f: F) -> Option<O>
where F: FnMut(T) -> Option<O> {
match t {
Some(t) => f(t),
None => None,
}
}
fn ret(inner: T) -> Self {
Some(inner)
}
}
impl<T, O, E> Monad<Result<O, E>> for Result<T, E> {
type Inner = T;
fn bind<F>(t: Result<T, E>, mut f: F) -> Result<O, E>
where F: FnMut(T) -> Result<O, E> {
match t {
Ok(t) => f(t),
Err(e) => Err(e),
}
}
fn ret(inner: T) -> Self {
Ok(inner)
}
}
impl<T, O> Monad<Vec<O>> for Vec<T> {
type Inner = T;
fn bind<F>(t: Self, mut f: F) -> Vec<O>
where F: FnMut(T) -> Vec<O> {
let mut acc: Vec<O> = Vec::new();
for v in t {
acc.append(&mut f(v));
}
acc
}
fn ret(inner: T) -> Vec<T> {
vec![inner]
}
}