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
use crate::monad::{Monad};
use std::iter::FromIterator;
pub struct ReaderT<'a, E, M> {
pub run_reader_t: Box< dyn 'a + Fn(E) -> M>,
}
impl<'a, A, E, M> ReaderT<'a, E, M>
where
E: 'a + Clone,
A: 'a + Clone,
M: 'a + Clone + Monad<Item=A> + FromIterator<A>,
{
pub fn pure(x: A) -> Self {
ReaderT { run_reader_t: Box::new( move |_| M::pure( x.clone() ))}
}
pub fn bind<B, N, F>(self, f: F) -> ReaderT<'a, E, N>
where
F: 'a + Fn(A) -> ReaderT<'a, E, N>,
B: 'a,
N: 'a + Monad<Item=B> + FromIterator<B>,
{
ReaderT { run_reader_t:
Box::new( move |e: E| {
let m = (* self.run_reader_t)( e.clone());
let g = |a| (* f(a).run_reader_t)( e.clone());
M::bind( m, g).collect::<N>()
})
}
}
pub fn initial_env(self, e: E) -> M {
(* self.run_reader_t) (e)
}
pub fn lift(m: M) -> ReaderT<'a, E, M> {
ReaderT { run_reader_t: Box::new( move |_| m.clone() )}
}
pub fn lift_iter<I>( it: I) -> ReaderT<'a, E, M>
where
I: 'a + Iterator<Item=A> + Clone,
{
ReaderT { run_reader_t: Box::new( move |_| it.clone().collect::<M>() )}
}
}
pub fn ask<'a, E: Clone, M: Monad<Item=E>>() -> ReaderT<'a, E, M> {
ReaderT { run_reader_t: Box::new(|e: E| M::pure( e.clone()))}
}
pub fn local<'a, E, M, F>(f: F, rdr: ReaderT<'a, E, M>) -> ReaderT<'a, E, M>
where
F: 'a + Fn(E) -> E,
E: 'a,
M: 'a,
{
ReaderT { run_reader_t:
Box::new(move |e: E| { (*rdr.run_reader_t) (f(e)) })
}
}
pub fn lift<'a, E: 'a, M: 'a + Clone>(m: M) -> ReaderT<'a, E, M> {
ReaderT { run_reader_t: Box::new( move |_| m.clone() )}
}
#[macro_export]
macro_rules! rdrt_mdo {
(lift $last_nested_monad:expr ) => [ReaderT::lift($last_nested_monad)];
(pure $last_expr:expr ) => [ReaderT::lift(vec!($last_expr))];
(guard $boolean:expr ; $($rest:tt)*) => [ReaderT::lift( if $boolean {vec![()]} else {vec![]}).bind( move |_| { rdrt_mdo!($($rest)*)} )];
(let $v:ident = $e:expr ; $($rest:tt)*) => [ReaderT::lift(vec![$e]).bind( move |$v| { rdrt_mdo!($($rest)*)} )];
(_ <- $monad:expr ; $($rest:tt)* ) => [ReaderT::bind(($monad), move |_| { rdrt_mdo!($($rest)*)} )];
($v:ident <- ask() ; $($rest:tt)* ) => [( ask() as ReaderT<'_, Env, Vec<Env>>).bind(
move |$v| { rdrt_mdo!($($rest)*)}) ];
($v:ident <- lift_iter $iterator:expr ; $($rest:tt)* ) => [ReaderT::<'_, Env, Vec<_>>::lift_iter($iterator).bind( move |$v| { rdrt_mdo!($($rest)*)} )];
(& $v:ident <- lift $nested_monad:expr ; $($rest:tt)* ) => [ReaderT::lift($nested_monad).bind( move |& $v| { rdrt_mdo!($($rest)*)} )];
($v:ident <- lift $nested_monad:expr ; $($rest:tt)* ) => [ReaderT::lift($nested_monad).bind( move |$v| { rdrt_mdo!($($rest)*)} )];
($v:ident <- $monad:expr ; $($rest:tt)* ) => [ReaderT::bind(($monad), move |$v| { rdrt_mdo!($($rest)*)} )];
($monad:expr ) => [$monad];
}