aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/data/collection/tree.lux
blob: 43f2f16c928c9b4ed6274c17b1b542b049faa586 (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
(.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)))

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

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

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

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