-
Notifications
You must be signed in to change notification settings - Fork 3
/
list.fnl
66 lines (56 loc) · 1.12 KB
/
list.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
(import-macros
{: mdo}
:fp.mdo-macros)
(local
{: has-type?}
(require :typed-fennel))
(local List {})
(local List-mt
{:__call
(λ [self T]
#(do
(assert
(List.list? $)
"Not a result")
(List.elim $ true
#(and $1
(assert
(has-type? $2 T)
"Unexpected List element type")))))})
(setmetatable List List-mt)
;;; Validation
(fn List.list? [xs]
(vim.islist xs))
;;; Construction
(fn List.new [...]
(let [t (table.pack ...)]
(tset t :n nil)
(setmetatable t List-mt)
t))
;;; Deconstruction
(fn List.elim [xs init f]
(-> xs
vim.iter
(: :fold init f)))
;;; Functor
(fn List.map [xs f]
(vim.tbl_map f xs))
;;; Monad
(fn List.pure [...]
[...])
(fn List.join [xss]
(local res [])
(each [_ xs (ipairs xss)]
(each [_ x (ipairs xs)]
(table.insert res x)))
res)
(fn List.>>= [xs f]
(local res [])
(each [_ x (ipairs xs)]
(each [_ y (ipairs (f x))]
(table.insert res y)))
res)
;;; Miscellaneous
(fn List.empty []
[])
List