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
106
107
108
109
110
111
112
113
114
115
use Partial;
use Partial::*;
use std::ops::{Deref, DerefMut};
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
pub struct Environment<T, U>
{
env: T,
data: Partial<U>
}
impl<T, U> Environment<T, U>
{
pub fn new(env: T, data: Partial<U>) -> Self {
Environment {
env: env,
data: data
}
}
pub fn value(env: T, data: U) -> Self {
Self::new(env, Partial::Value(data))
}
pub fn fake(env: T, data: U) -> Self {
Self::new(env, Partial::Fake(data))
}
pub fn nothing(env: T) -> Self {
Self::new(env, Partial::Nothing)
}
pub fn unwrap(self) -> U {
self.data.unwrap()
}
pub fn decompose(self) -> (T, Partial<U>) {
(self.env, self.data)
}
pub fn expect(self, msg: &str) -> U {
self.data.expect(msg)
}
pub fn ensure(self, msg: &str) -> Self {
Environment::new(self.env, self.data.ensure(msg))
}
pub fn unwrap_or_else<F>(self, f: F) -> U where
F: FnOnce() -> U
{
self.data.unwrap_or_else(f)
}
pub fn map<R, F: FnOnce(U) -> R>(self, f: F) -> Environment<T, R> {
match self.data {
Value(x) => Environment::value(self.env, f(x)),
Fake(x) => Environment::fake(self.env, f(x)),
Nothing => Environment::nothing(self.env)
}
}
pub fn and_then<R, F: FnOnce(T, U) -> Environment<T, R>>(self, f: F) -> Environment<T, R> {
match self.data {
Value(x) => f(self.env, x),
Fake(x) => {
let r = f(self.env, x);
match r.data {
Value(x) => Environment::fake(r.env, x),
x => Environment::new(r.env, x)
}
}
Nothing => Environment::nothing(self.env)
}
}
pub fn and_next<R, F: FnOnce(T, U) -> Environment<T, R>>(self, f: F) -> Environment<T, R> {
match self.data {
Value(x) => f(self.env, x),
_ => Environment::nothing(self.env)
}
}
}
impl<T, U> Deref for Environment<T, U> {
type Target = T;
fn deref(&self) -> &T {
&self.env
}
}
impl<T, U> DerefMut for Environment<T, U> {
fn deref_mut(&mut self) -> &mut T {
&mut self.env
}
}