-
Notifications
You must be signed in to change notification settings - Fork 3
/
option.fnl
74 lines (65 loc) · 1.39 KB
/
option.fnl
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
(import-macros
{: mdo}
:fp.mdo-macros)
(local
{: has-type?}
(require :typed-fennel))
(local Option {})
;;; Metatable
(local Option-mt
{:__call
(λ [self T]
#(do
(when (not (Option.option? $))
(error "Not an Option"))
(Option.elim $
true
#(or (has-type? $ T)
(error "Unexpected Some type")))))})
(setmetatable Option Option-mt)
;;; Validation
(fn Option.some? [mx]
(match mx
[:some & _] true
_ false))
(fn Option.none? [mx]
(match mx
[:none] true
_ false))
(fn Option.option? [mx]
(or (Option.some? mx)
(Option.none? mx)))
;;; Construction
(fn Option.some [...]
[:some ...])
(fn Option.none [...]
[:none])
(fn Option.new [x]
(match x
(nil) (Option.none)
_ (Option.some x)))
;;; Destruction
(fn Option.elim [x d f]
(match x
[:some & some] (f (unpack some))
_ d))
;;; Monad
(fn Option.pure [...]
(Option.ok ...))
(fn Option.join [mx]
(match mx
[:some [:some & x]] (values (unpack x))))
(fn Option.>>= [mx f]
(match mx
[:some & x] (f (unpack x))
_ mx))
;;; Miscellaneous
(fn Option.unwrap [mx]
(match mx
[:some & x] (values (unpack x))
[:none] nil))
(fn Option.unwrap! [mx]
(match mx
[:some & x] (values (unpack x))
[:none] (error "Tried to unwrap a none")))
Option