-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmaybe.rs
133 lines (104 loc) · 3.57 KB
/
maybe.rs
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use crate::{common::*, functional::Func};
pub use base::*;
pub use ops::*;
mod base {
// maybe def
/// A trait analogous to [Option](std::option::Option).
pub trait Maybe {}
// just def
/// A type analogous to `Some`.
pub struct Just<T>(T);
impl<T> Maybe for Just<T> {}
// nothing def
/// A type analogous to `None`.
pub struct Nothing;
impl Maybe for Nothing {}
}
mod ops {
use super::*;
typ! {
pub fn Unwrap<value>(Just::<value>: Maybe) {
value
}
pub fn UnwrapOr<maybe, default>(maybe: Maybe, default: _) {
match maybe {
#[generics(value)]
Just::<value> => value,
Nothing => default,
}
}
pub fn IsJust<maybe>(maybe: Maybe) -> Bit {
match maybe {
#[generics(value)]
Just::<value> => true,
Nothing => false,
}
}
pub fn IsNothing<maybe>(maybe: Maybe) -> Bit {
match maybe {
#[generics(value)]
Just::<value> => false,
Nothing => true,
}
}
pub fn Map<maybe, func>(maybe: Maybe, func: _) -> Maybe {
match maybe {
#[generics(value)]
Just::<value> => {
let new_value = func.Func(value);
Just::<new_value>
}
Nothing => Nothing
}
}
}
}
// tests
#[cfg(test)]
mod tests {
// use super::*;
// use crate::{
// boolean::Boolean,
// control::{IfElsePredicate, IfElsePredicateOutput, IfSameOutput},
// functional::{Applicative, FMap},
// numeric::AddOneMap,
// };
// use typenum::{consts::*, GrEq, IsGreaterOrEqual, Unsigned};
// // unwrap
// type Opt1 = Just<U3>;
// type Opt2 = Nothing;
// type SameOp<Lhs, Rhs> = IfSameOutput<(), Lhs, Rhs>;
// type Assert1 = SameOp<Unwrap<Opt1>, U3>;
// type Assert2 = SameOp<UnwrapOr<Opt1, U0>, U3>;
// type Assert3 = SameOp<UnwrapOr<Opt2, U0>, U0>;
// // map
// struct BoxFunc;
// impl<Input> Map<Input> for BoxFunc {
// type Output = Box<Input>;
// }
// type Assert4 = IfSameOutput<(), MaybeMap<Just<i8>, BoxFunc>, Just<Box<i8>>>;
// type Assert5 = IfSameOutput<(), MaybeMap<Nothing, BoxFunc>, Nothing>;
// // filter
// struct ThresholdFunc;
// impl<Input> Map<Input> for ThresholdFunc
// where
// Input: Unsigned + IsGreaterOrEqual<U4>,
// GrEq<Input, U4>: Boolean,
// Just<Input>: IfElsePredicate<GrEq<Input, U4>, Nothing>,
// {
// type Output = IfElsePredicateOutput<Just<Input>, GrEq<Input, U4>, Nothing>;
// }
// type Assert6 = IfSameOutput<(), MaybeFilter<Just<U8>, ThresholdFunc>, Just<U8>>;
// type Assert7 = IfSameOutput<(), MaybeFilter<Just<U2>, ThresholdFunc>, Nothing>;
// type Assert8 = IfSameOutput<(), MaybeFilter<Nothing, ThresholdFunc>, Nothing>;
// // FMap
// type Assert9 = IfSameOutput<(), FMap<Nothing, AddOneMap>, Nothing>;
// type Assert10 = IfSameOutput<(), FMap<Just<U8>, AddOneMap>, Just<U9>>;
// // Applicative
// type Assert11 = IfSameOutput<(), Applicative<Nothing, Nothing>, Nothing>;
// type Assert12 = IfSameOutput<(), Applicative<Just<AddOneMap>, Nothing>, Nothing>;
// type Assert13 = IfSameOutput<(), Applicative<Nothing, Just<U7>>, Nothing>;
// type Assert14 = IfSameOutput<(), Applicative<Just<AddOneMap>, Just<U7>>, Just<U8>>;
#[test]
fn maybe_test() {}
}