/
maybe.clay
88 lines (57 loc) · 2.03 KB
/
maybe.clay
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
/// @section Maybe[T]
variant Maybe[T] (Nothing, T);
record Nothing ();
/// @section constructors
[T]
forceinline overload Maybe(x:T) : Maybe[T] = Maybe[T](x);
[T]
forceinline overload Maybe[T]() : Maybe[T] = Maybe[T](Nothing());
forceinline nothing(T) = Maybe[T]();
[T]
define Maybe?(#T) : Bool;
overload Maybe?(T) : Bool = false;
[T] overload Maybe?(#Maybe[T]) : Bool = true;
/// @section nothing?
forceinline nothing?(x) : Bool = variantIs?(x, Nothing);
forceinline just?(x) : Bool = variantIs?(x, Type(just(x)));
define just;
[T]
forceinline overload just(forward m: Maybe[T]) = forward variantAs(m, T);
[T]
forceinline overload just(m: Maybe[T], dflt: T) = maybe(m, v => v, () => dflt);
/// @section maybe function
private define maybeValue;
forceinline default maybeValue(T, forward x, thenFn, ..elseFn) = forward ..thenFn(x);
forceinline default maybeValue(T, forward n: Nothing, thenFn, elseFn) = forward ..elseFn();
// if the thenFn returns Maybe[T]s, have the default else case return nothing(T)s
[T, F when allValues?(Maybe?, ..CallOutputTypes(call, F, T))]
forceinline overload maybeValue(#T, forward n: Nothing, thenFn:F)
= ..mapValues(call, ..CallOutputTypes(call, F, T));
[T]
forceinline maybe(forward m:Maybe[T], thenFn, ..elseFn)
= forward ..maybeValue(#T, *m, thenFn, ..elseFn);
/// @section require function
record ValueMissing ();
instance Exception (ValueMissing);
define require;
[T]
forceinline overload require(forward m:Maybe[T], fn) {
if (nothing?(m))
throw ValueMissing();
return forward ..fn(variantAs(m, T));
}
[T]
forceinline overload require(forward m:Maybe[T]) {
if (nothing?(m))
throw ValueMissing();
return forward variantAs(m, T);
}
/// @section maybe as iterator value
[T] forceinline overload hasValue?(m:Maybe[T]) : Bool = just?(m);
[T] forceinline overload getValue(forward m:Maybe[T]) = forward just(m);
forceinline getMaybeValue(v) {
if (hasValue?(v))
return Maybe(getValue(v));
else
return nothing(Type(getValue(v)));
}