aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/data/collection/tree.lux
blob: d1f9d46ba241df1b1b4ba02e492ae6768f95f3a7 (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
(.using
 [library
  [lux (.except)
   [abstract
    [functor (.only Functor)]
    [equivalence (.only Equivalence)]
    [mix (.only Mix)]
    [monad (.only do)]]
   [control
    ["<>" parser (.only)
     ["<[0]>" code (.only Parser)]]]
   [data
    [collection
     ["[0]" list (.open: "[1]#[0]" monad mix)]]]
   [macro
    [syntax (.only syntax)]
    ["[0]" code]]]])

(type: .public (Tree a)
  (Record
   [#value a
    #children (List (Tree a))]))

(def .public (flat tree)
  (All (_ a) (-> (Tree a) (List a)))
  (|> tree
      (the #children)
      (list#each flat)
      list#conjoint
      {.#Item (the #value tree)}))

(def .public (leaf value)
  (All (_ a) (-> a (Tree a)))
  [#value value
   #children (list)])

(def .public (branch value children)
  (All (_ a) (-> a (List (Tree a)) (Tree a)))
  [#value value
   #children children])

(type: Tree_Code
  (Rec Tree_Code
    [Code (List Tree_Code)]))

(def tree^
  (Parser Tree_Code)
  (|> (|>> <>.some
           <code>.variant
           (<>.and <code>.any))
      <>.rec
      <>.some
      <code>.variant
      (<>.else (list))
      (<>.and <code>.any)))

(def .public tree
  (syntax (_ [root tree^])
    (in (list (loop (again [[value children] root])
                (` [#value (~ value)
                    #children (list (~+ (list#each again children)))]))))))

(def .public (equivalence super)
  (All (_ a) (-> (Equivalence a) (Equivalence (Tree a))))
  (implementation
   (def (= tx ty)
     (and (at super = (the #value tx) (the #value ty))
          (at (list.equivalence (equivalence super)) = (the #children tx) (the #children ty))))))

(def .public functor
  (Functor Tree)
  (implementation
   (def (each f fa)
     [#value (f (the #value fa))
      #children (list#each (each f)
                           (the #children fa))])))

(def .public mix
  (Mix Tree)
  (implementation
   (def (mix f init tree)
     (list#mix (function (_ tree' init') (mix f init' tree'))
               (f (the #value tree)
                  init)
               (the #children tree)))))