aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/data/collection/queue.lux
blob: 54c1024b68d903674bcd7dfcd26d4b752e07df76 (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
(.using
 [library
  [lux (.except list)
   [abstract
    [equivalence (.only Equivalence)]
    [functor (.only Functor)]]
   [data
    [collection
     ["[0]" list (.open: "[1]#[0]" monoid functor)]]]
   [math
    [number
     ["n" nat]]]]])

(type: .public (Queue a)
  (Record
   [#front (List a)
    #rear (List a)]))

(def .public empty
  Queue
  [#front (.list)
   #rear (.list)])

(def .public (of_list entries)
  (All (_ a) (-> (List a) (Queue a)))
  [#front entries
   #rear (.list)])

(def .public (list queue)
  (All (_ a) (-> (Queue a) (List a)))
  (let [(open "_[0]") queue]
    (list#composite _#front (list.reversed _#rear))))

(def .public front
  (All (_ a) (-> (Queue a) (Maybe a)))
  (|>> (the #front) list.head))

(def .public (size queue)
  (All (_ a) (-> (Queue a) Nat))
  (let [(open "_[0]") queue]
    (n.+ (list.size _#front)
         (list.size _#rear))))

(def .public empty?
  (All (_ a) (-> (Queue a) Bit))
  (|>> (the #front) list.empty?))

(def .public (member? equivalence queue member)
  (All (_ a) (-> (Equivalence a) (Queue a) a Bit))
  (let [(open "_[0]") queue]
    (or (list.member? equivalence _#front member)
        (list.member? equivalence _#rear member))))

(def .public (next queue)
  (All (_ a) (-> (Queue a) (Queue a)))
  (case (the #front queue)
    ... Empty...
    (pattern (.list))
    queue

    ... Front has dried up...
    (pattern (.list _))
    (|> queue
        (has #front (list.reversed (the #rear queue)))
        (has #rear (.list)))

    ... Consume front!
    (pattern (list.partial _ front'))
    (|> queue
        (has #front front'))))

(def .public (end val queue)
  (All (_ a) (-> a (Queue a) (Queue a)))
  (case (the #front queue)
    {.#End}
    (has #front (.list val) queue)

    _
    (revised #rear (|>> {.#Item val}) queue)))

(def .public (equivalence super)
  (All (_ a) (-> (Equivalence a) (Equivalence (Queue a))))
  (implementation
   (def (= reference subject)
     (at (list.equivalence super) =
         (..list reference)
         (..list subject)))))

(def .public functor
  (Functor Queue)
  (implementation
   (def (each f fa)
     [#front (|> fa (the #front) (list#each f))
      #rear (|> fa (the #rear) (list#each f))])))