aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/data/collection/queue.lux
blob: 12bb5b68edb2286982a7124b44096a787d1c9ecf (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
(.module:
  [library
   [lux {"-" [list]}
    [abstract
     [equivalence {"+" [Equivalence]}]
     [functor {"+" [Functor]}]]
    [data
     [collection
      ["." list ("#\." 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 [(^slots [#front #rear]) queue]
    (list\composite front (list.reversed rear))))

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

(def: .public (size queue)
  (All (_ a) (-> (Queue a) Nat))
  (let [(^slots [#front #rear]) queue]
    (n.+ (list.size front)
         (list.size rear))))

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

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

(def: .public (next queue)
  (All (_ a) (-> (Queue a) (Queue a)))
  (case (value@ #front queue)
    ... Empty...
    (^ (.list))
    queue

    ... Front has dried up...
    (^ (.list _))
    (|> queue
        (with@ #front (list.reversed (value@ #rear queue)))
        (with@ #rear (.list)))

    ... Consume front!
    (^ (.list& _ front'))
    (|> queue
        (with@ #front front'))))

(def: .public (end val queue)
  (All (_ a) (-> a (Queue a) (Queue a)))
  (case (value@ #front queue)
    #.End
    (with@ #front (.list val) queue)

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

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

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