blob: 2cd4b6794d09541cddb6914d54725ee1ae9c61d1 (
plain)
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
|
(.require
[library
[lux (.except left right)
[abstract
[equivalence (.only Equivalence)]
[hash (.only Hash)]]
[data
[collection
["[0]" list (.use "[1]#[0]" mix)]]]]])
(with_template [<right?> <name>]
[(def .public (<name> value)
(All (_ left right)
(-> <name> (Or left right)))
{0 <right?> value})]
[#0 left]
[#1 right])
(def .public (either on_left on_right)
(All (_ a b c)
(-> (-> a c) (-> b c)
(-> (Or a b) c)))
(function (_ input)
(when input
{0 #0 l} (on_left l)
{0 #1 r} (on_right r))))
(def .public (then on_left on_right)
(All (_ l l' r r')
(-> (-> l l') (-> r r')
(-> (Or l r) (Or l' r'))))
(function (_ input)
(when input
{0 #0 l} {0 #0 (on_left l)}
{0 #1 r} {0 #1 (on_right r)})))
(with_template [<right?> <side> <name>]
[(def .public (<name> it)
(All (_ t0 t1) (-> (List (Or t0 t1)) (List <side>)))
... TODO: Use the more obvious implementation once "tail recursion modulo cons" is added to the compiler.
(list#mix (function (_ head tail)
(when head
{0 <right?> head}
(list.partial head tail)
_
tail))
(list)
(list.reversed it)))]
[#0 t0 lefts]
[#1 t1 rights]
)
(def .public (partition xs)
(All (_ a b) (-> (List (Or a b)) [(List a) (List b)]))
(when xs
{.#End}
[{.#End} {.#End}]
{.#Item x xs'}
(let [[lefts rights] (partition xs')]
(when x
{0 #0 x'} [{.#Item x' lefts} rights]
{0 #1 x'} [lefts {.#Item x' rights}]))))
(def .public (equivalence left right)
(All (_ l r) (-> (Equivalence l) (Equivalence r) (Equivalence (Or l r))))
(implementation
(def (= reference sample)
(when [reference sample]
[{.#Left reference} {.#Left sample}]
(of left = reference sample)
[{.#Right reference} {.#Right sample}]
(of right = reference sample)
_
false))))
(def .public (hash left right)
(All (_ l r) (-> (Hash l) (Hash r) (Hash (Or l r))))
(implementation
(def equivalence
(..equivalence (of left equivalence)
(of right equivalence)))
(def (hash value)
(.nat (when value
{.#Left value}
(.int_*# +2 (.int (of left hash value)))
{.#Right value}
(.int_*# +3 (.int (of right hash value))))))))
|