aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/data/sum.lux
blob: 7c869601207b71e90ccfa4d24de10b2de91bc66a (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
(.module:
  [library
   [lux #*
    [abstract
     [equivalence (#+ Equivalence)]
     [hash (#+ Hash)]]]])

(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)
    (case 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)
    (case input
      (0 #0 l) (0 #0 (on_left l))
      (0 #1 r) (0 #1 (on_right r)))))

(template [<name> <side> <right?>]
  [(def: .public (<name> items)
     (All (_ a b) (-> (List (Or a b)) (List <side>)))
     (case items
       #.End
       #.End
       
       (#.Item (0 <right?> x) items')
       (#.Item [x (<name> items')])
       
       (#.Item _ items')
       (<name> items')))]

  [lefts  a #0]
  [rights b #1]
  )

(def: .public (partition xs)
  (All (_ a b) (-> (List (Or a b)) [(List a) (List b)]))
  (case xs
    #.End
    [#.End #.End]

    (#.Item x xs')
    (let [[lefts rights] (partition xs')]
      (case 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)
     (case [reference sample]
       [(#.Left reference) (#.Left sample)]
       (\ left = reference sample)

       [(#.Right reference) (#.Right sample)]
       (\ right = reference sample)

       _
       false))))

(def: .public (hash left right)
  (All (_ l r) (-> (Hash l) (Hash r) (Hash (Or l r))))
  (implementation
   (def: &equivalence
     (..equivalence (\ left &equivalence)
                    (\ right &equivalence)))
   (def: (hash value)
     (case value
       (#.Left value)
       (\ left hash value)

       (#.Right value)
       (\ right hash value)))))