blob: c3e20ce08364009b0141feeda844293490aab841 (
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
|
(.module:
[lux #*
[abstract
[predicate (#+ Predicate)]
["." monoid (#+ Monoid)]]
[type (#+ :by-example)
[abstract (#+ abstract: :abstraction :representation)]]])
(abstract: #export (Tree @ t v)
{#monoid (Monoid t)
#tag t
#root (| v
[(Tree @ t v) (Tree @ t v)])}
(signature: #export (Builder @ t)
(: (All [v]
(-> t v (Tree @ t v)))
leaf)
(: (All [v]
(-> (Tree @ t v)
(Tree @ t v)
(Tree @ t v)))
branch))
(template [<name> <tag> <output>]
[(def: #export <name>
(All [@ t v] (-> (Tree @ t v) <output>))
(|>> :representation (get@ <tag>)))]
[tag #tag t]
[root #root (Either v [(Tree @ t v) (Tree @ t v)])]
)
(structure: #export (builder monoid)
(All [t] (Ex [@] (-> (Monoid t) (Builder @ t))))
(def: (leaf tag value)
(:abstraction
{#monoid monoid
#tag tag
#root (0 #0 value)}))
(def: (branch left right)
(:abstraction
{#monoid monoid
#tag (\ monoid compose (..tag left) (..tag right))
#root (0 #1 [left right])})))
(def: #export (value tree)
(All [@ t v] (-> (Tree @ t v) v))
(case (get@ #root (:representation tree))
(0 #0 value)
value
(0 #1 [left right])
(value left)))
(def: #export (search predicate tree)
(All [@ t v] (-> (Predicate t) (Tree @ t v) (Maybe v)))
(let [[monoid tag root] (:representation tree)]
(if (predicate tag)
(let [(^open "tag//.") monoid]
(loop [_tag tag//identity
_node root]
(case _node
(0 #0 value)
(#.Some value)
(0 #1 [left right])
(let [shifted-tag (tag//compose _tag (..tag left))]
(if (predicate shifted-tag)
(recur _tag (get@ #root (:representation left)))
(recur shifted-tag (get@ #root (:representation right))))))))
#.None)))
)
(def: #export (found? predicate tree)
(All [@ t v] (-> (Predicate t) (Tree @ t v) Bit))
(case (..search predicate tree)
(#.Some _)
true
#.None
false))
|