@grain/stdlib 0.5.13 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +201 -0
- package/LICENSE +1 -1
- package/README.md +25 -2
- package/array.gr +1512 -199
- package/array.md +2032 -94
- package/bigint.gr +239 -140
- package/bigint.md +450 -106
- package/buffer.gr +595 -102
- package/buffer.md +903 -145
- package/bytes.gr +401 -110
- package/bytes.md +551 -63
- package/char.gr +228 -49
- package/char.md +373 -7
- package/exception.gr +26 -12
- package/exception.md +29 -5
- package/float32.gr +130 -109
- package/float32.md +185 -57
- package/float64.gr +112 -99
- package/float64.md +185 -57
- package/hash.gr +62 -40
- package/hash.md +27 -3
- package/int16.gr +430 -0
- package/int16.md +618 -0
- package/int32.gr +200 -269
- package/int32.md +254 -289
- package/int64.gr +142 -225
- package/int64.md +254 -289
- package/int8.gr +511 -0
- package/int8.md +786 -0
- package/json.gr +2071 -0
- package/json.md +646 -0
- package/list.gr +120 -68
- package/list.md +125 -80
- package/map.gr +560 -57
- package/map.md +672 -56
- package/marshal.gr +239 -227
- package/marshal.md +36 -4
- package/number.gr +626 -676
- package/number.md +738 -153
- package/option.gr +33 -35
- package/option.md +58 -42
- package/package.json +2 -2
- package/path.gr +148 -187
- package/path.md +47 -96
- package/pervasives.gr +75 -416
- package/pervasives.md +85 -180
- package/priorityqueue.gr +433 -74
- package/priorityqueue.md +422 -54
- package/queue.gr +362 -80
- package/queue.md +433 -38
- package/random.gr +67 -75
- package/random.md +68 -40
- package/range.gr +135 -63
- package/range.md +198 -43
- package/rational.gr +284 -0
- package/rational.md +545 -0
- package/regex.gr +933 -1066
- package/regex.md +59 -60
- package/result.gr +23 -25
- package/result.md +54 -39
- package/runtime/atof/common.gr +78 -82
- package/runtime/atof/common.md +22 -10
- package/runtime/atof/decimal.gr +102 -127
- package/runtime/atof/decimal.md +28 -7
- package/runtime/atof/lemire.gr +56 -71
- package/runtime/atof/lemire.md +9 -1
- package/runtime/atof/parse.gr +83 -110
- package/runtime/atof/parse.md +12 -2
- package/runtime/atof/slow.gr +28 -35
- package/runtime/atof/slow.md +9 -1
- package/runtime/atof/table.gr +19 -18
- package/runtime/atof/table.md +10 -2
- package/runtime/atoi/parse.gr +153 -136
- package/runtime/atoi/parse.md +50 -1
- package/runtime/bigint.gr +410 -517
- package/runtime/bigint.md +71 -57
- package/runtime/compare.gr +176 -85
- package/runtime/compare.md +31 -1
- package/runtime/dataStructures.gr +144 -32
- package/runtime/dataStructures.md +267 -31
- package/runtime/debugPrint.gr +34 -15
- package/runtime/debugPrint.md +37 -5
- package/runtime/equal.gr +53 -52
- package/runtime/equal.md +30 -1
- package/runtime/exception.gr +38 -47
- package/runtime/exception.md +10 -8
- package/runtime/gc.gr +23 -152
- package/runtime/gc.md +13 -17
- package/runtime/malloc.gr +31 -31
- package/runtime/malloc.md +11 -3
- package/runtime/numberUtils.gr +193 -174
- package/runtime/numberUtils.md +29 -9
- package/runtime/numbers.gr +1695 -1021
- package/runtime/numbers.md +1098 -134
- package/runtime/string.gr +543 -245
- package/runtime/string.md +76 -6
- package/runtime/unsafe/constants.gr +30 -13
- package/runtime/unsafe/constants.md +80 -0
- package/runtime/unsafe/conv.gr +55 -28
- package/runtime/unsafe/conv.md +41 -9
- package/runtime/unsafe/memory.gr +10 -30
- package/runtime/unsafe/memory.md +15 -19
- package/runtime/unsafe/tags.gr +37 -21
- package/runtime/unsafe/tags.md +88 -8
- package/runtime/unsafe/wasmf32.gr +30 -36
- package/runtime/unsafe/wasmf32.md +64 -56
- package/runtime/unsafe/wasmf64.gr +30 -36
- package/runtime/unsafe/wasmf64.md +64 -56
- package/runtime/unsafe/wasmi32.gr +49 -66
- package/runtime/unsafe/wasmi32.md +102 -94
- package/runtime/unsafe/wasmi64.gr +52 -79
- package/runtime/unsafe/wasmi64.md +108 -100
- package/runtime/utils/printing.gr +13 -15
- package/runtime/utils/printing.md +11 -3
- package/runtime/wasi.gr +294 -295
- package/runtime/wasi.md +62 -42
- package/set.gr +574 -64
- package/set.md +634 -54
- package/stack.gr +181 -64
- package/stack.md +271 -42
- package/string.gr +453 -533
- package/string.md +241 -151
- package/uint16.gr +369 -0
- package/uint16.md +585 -0
- package/uint32.gr +470 -0
- package/uint32.md +737 -0
- package/uint64.gr +471 -0
- package/uint64.md +737 -0
- package/uint8.gr +369 -0
- package/uint8.md +585 -0
- package/uri.gr +1093 -0
- package/uri.md +477 -0
- package/{sys → wasi}/file.gr +914 -500
- package/{sys → wasi}/file.md +454 -50
- package/wasi/process.gr +292 -0
- package/{sys → wasi}/process.md +164 -6
- package/wasi/random.gr +77 -0
- package/wasi/random.md +80 -0
- package/{sys → wasi}/time.gr +15 -22
- package/{sys → wasi}/time.md +5 -5
- package/immutablearray.gr +0 -929
- package/immutablearray.md +0 -1038
- package/immutablemap.gr +0 -493
- package/immutablemap.md +0 -479
- package/immutablepriorityqueue.gr +0 -360
- package/immutablepriorityqueue.md +0 -291
- package/immutableset.gr +0 -498
- package/immutableset.md +0 -449
- package/runtime/debug.gr +0 -2
- package/runtime/debug.md +0 -6
- package/runtime/unsafe/errors.gr +0 -36
- package/runtime/unsafe/errors.md +0 -204
- package/sys/process.gr +0 -254
- package/sys/random.gr +0 -79
- package/sys/random.md +0 -66
package/queue.gr
CHANGED
|
@@ -1,137 +1,419 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* A queue is a FIFO (first-in-first-out) data structure where new
|
|
3
|
+
* values are added to the end and retrieved or removed from the beginning.
|
|
4
|
+
*
|
|
5
|
+
* The default implementation is mutable, but an immutable queue
|
|
6
|
+
* implementation is available in the `Immutable` submodule.
|
|
7
|
+
*
|
|
8
|
+
* @example from "queue" include Queue
|
|
9
|
+
*
|
|
4
10
|
* @since v0.2.0
|
|
11
|
+
*/
|
|
12
|
+
module Queue
|
|
13
|
+
|
|
14
|
+
from "list" include List
|
|
15
|
+
from "array" include Array
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A mutable FIFO (first-in-first-out) data structure.
|
|
19
|
+
*/
|
|
20
|
+
abstract record Queue<a> {
|
|
21
|
+
mut size: Number,
|
|
22
|
+
mut array: Array<Option<a>>,
|
|
23
|
+
mut headIndex: Number,
|
|
24
|
+
mut tailIndex: Number, // tail points to where the next element should be inserted
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new queue with an initial storage of the given size. As values are
|
|
29
|
+
* added or removed, the internal storage may grow or shrink. Generally, you
|
|
30
|
+
* won’t need to care about the storage size of your map and can use the
|
|
31
|
+
* default size.
|
|
32
|
+
*
|
|
33
|
+
* @param size: The initial storage size of the queue
|
|
34
|
+
* @returns An empty queue
|
|
35
|
+
*
|
|
36
|
+
* @since v0.6.0
|
|
37
|
+
*/
|
|
38
|
+
provide let make = (size=16) => {
|
|
39
|
+
{ size: 0, array: Array.make(size, None), headIndex: 0, tailIndex: 0 }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Checks if the given queue contains no items.
|
|
5
44
|
*
|
|
6
|
-
* @
|
|
45
|
+
* @param queue: The queue to check
|
|
46
|
+
* @returns `true` if the queue has no items or `false` otherwise
|
|
47
|
+
*
|
|
48
|
+
* @since v0.6.0
|
|
7
49
|
*/
|
|
8
|
-
|
|
50
|
+
provide let isEmpty = queue => queue.size == 0
|
|
9
51
|
|
|
10
52
|
/**
|
|
11
|
-
*
|
|
53
|
+
* Computes the size of the input queue.
|
|
54
|
+
*
|
|
55
|
+
* @param queue: The queue to inspect
|
|
56
|
+
* @returns The count of the items in the queue
|
|
57
|
+
*
|
|
58
|
+
* @since v0.6.0
|
|
12
59
|
*/
|
|
60
|
+
provide let size = queue => queue.size
|
|
13
61
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Provides the value at the beginning of the queue, if it exists.
|
|
64
|
+
*
|
|
65
|
+
* @param queue: The queue to inspect
|
|
66
|
+
* @returns `Some(value)` containing the value at the beginning of the queue or `None` otherwise.
|
|
67
|
+
*
|
|
68
|
+
* @since v0.6.0
|
|
69
|
+
*/
|
|
70
|
+
provide let peek = queue => {
|
|
71
|
+
if (queue.size == 0) None else queue.array[queue.headIndex]
|
|
17
72
|
}
|
|
18
73
|
|
|
19
74
|
/**
|
|
20
|
-
*
|
|
75
|
+
* Adds a new item to the end of the queue.
|
|
76
|
+
*
|
|
77
|
+
* @param value: The item to be added
|
|
78
|
+
* @param queue: The queue being updated
|
|
79
|
+
*
|
|
80
|
+
* @since v0.6.0
|
|
21
81
|
*/
|
|
82
|
+
provide let push = (value, queue) => {
|
|
83
|
+
let arrLen = Array.length(queue.array)
|
|
84
|
+
// expand the array if needed
|
|
85
|
+
if (arrLen == 0) {
|
|
86
|
+
queue.array = Array.make(1, None)
|
|
87
|
+
} else if (queue.size == arrLen) {
|
|
88
|
+
let newArray = Array.make(arrLen * 2, None)
|
|
89
|
+
|
|
90
|
+
newArray[0] = queue.array[queue.headIndex]
|
|
91
|
+
let mut insertI = 1
|
|
92
|
+
let mut currI = (queue.headIndex + 1) % arrLen
|
|
93
|
+
while (currI != queue.tailIndex) {
|
|
94
|
+
newArray[insertI] = queue.array[currI]
|
|
95
|
+
insertI += 1
|
|
96
|
+
currI = (currI + 1) % arrLen
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
queue.headIndex = 0
|
|
100
|
+
queue.tailIndex = arrLen
|
|
101
|
+
queue.array = newArray
|
|
102
|
+
}
|
|
103
|
+
queue.array[queue.tailIndex] = Some(value)
|
|
104
|
+
queue.tailIndex = (queue.tailIndex + 1) % Array.length(queue.array)
|
|
105
|
+
queue.size += 1
|
|
106
|
+
}
|
|
22
107
|
|
|
23
108
|
/**
|
|
24
|
-
*
|
|
109
|
+
* Removes the item at the beginning of the queue.
|
|
25
110
|
*
|
|
26
|
-
* @
|
|
111
|
+
* @param queue: The queue being updated
|
|
112
|
+
* @returns The element removed from the queue
|
|
113
|
+
*
|
|
114
|
+
* @since v0.6.0
|
|
27
115
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
116
|
+
provide let pop = queue => {
|
|
117
|
+
if (queue.size == 0) {
|
|
118
|
+
None
|
|
119
|
+
} else {
|
|
120
|
+
let elem = queue.array[queue.headIndex]
|
|
121
|
+
queue.array[queue.headIndex] = None
|
|
122
|
+
queue.headIndex = (queue.headIndex + 1) % Array.length(queue.array)
|
|
123
|
+
queue.size -= 1
|
|
124
|
+
elem
|
|
125
|
+
}
|
|
31
126
|
}
|
|
32
127
|
|
|
33
128
|
/**
|
|
34
|
-
*
|
|
129
|
+
* Converts a queue into a list of its elements.
|
|
35
130
|
*
|
|
36
|
-
* @
|
|
131
|
+
* @param queue: The queue to convert
|
|
132
|
+
* @returns A list containing all queue values
|
|
37
133
|
*
|
|
38
|
-
* @
|
|
134
|
+
* @since v0.6.0
|
|
135
|
+
*/
|
|
136
|
+
provide let toList = queue => {
|
|
137
|
+
let lst = List.init(
|
|
138
|
+
queue.size,
|
|
139
|
+
i =>
|
|
140
|
+
match (queue.array[(queue.headIndex + i) % Array.length(queue.array)]) {
|
|
141
|
+
Some(n) => n,
|
|
142
|
+
None =>
|
|
143
|
+
fail "Impossible: Attempted to access non-existent bucket in Queue.toList",
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
lst
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Creates a queue from a list.
|
|
39
151
|
*
|
|
40
|
-
* @
|
|
152
|
+
* @param list: The list to convert
|
|
153
|
+
* @returns A queue containing all list values
|
|
154
|
+
*
|
|
155
|
+
* @since v0.6.0
|
|
41
156
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
157
|
+
provide let fromList = list => {
|
|
158
|
+
let queue = make(size=List.length(list))
|
|
159
|
+
List.forEach(e => push(e, queue), list)
|
|
160
|
+
queue
|
|
44
161
|
}
|
|
45
162
|
|
|
46
163
|
/**
|
|
47
|
-
*
|
|
164
|
+
* Clears the queue by removing all of its elements
|
|
48
165
|
*
|
|
49
|
-
* @param queue: The queue to
|
|
50
|
-
* @returns `true` if the given queue is empty or `false` otherwise
|
|
166
|
+
* @param queue: The queue to clear
|
|
51
167
|
*
|
|
52
|
-
* @since v0.
|
|
168
|
+
* @since v0.6.0
|
|
53
169
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
170
|
+
provide let clear = queue => {
|
|
171
|
+
queue.size = 0
|
|
172
|
+
Array.fill(None, queue.array)
|
|
173
|
+
queue.headIndex = 0
|
|
174
|
+
queue.tailIndex = 0
|
|
59
175
|
}
|
|
60
176
|
|
|
61
177
|
/**
|
|
62
|
-
*
|
|
178
|
+
* Produces a shallow copy of the input queue.
|
|
63
179
|
*
|
|
64
|
-
* @param queue: The queue to
|
|
65
|
-
* @returns
|
|
180
|
+
* @param queue: The queue to copy
|
|
181
|
+
* @returns A new queue containing the elements from the input
|
|
66
182
|
*
|
|
67
|
-
* @since v0.
|
|
68
|
-
* @history v0.2.0: Originally named `head`
|
|
69
|
-
* @history v0.3.2: Deprecated `head` function
|
|
70
|
-
* @history v0.4.0: Removed `head` function
|
|
183
|
+
* @since v0.6.0
|
|
71
184
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
{ forwards, backwards } => List.head(forwards),
|
|
76
|
-
}
|
|
185
|
+
provide let copy = queue => {
|
|
186
|
+
let { size, array, headIndex, tailIndex } = queue
|
|
187
|
+
{ size, array: Array.copy(array), headIndex, tailIndex }
|
|
77
188
|
}
|
|
78
189
|
|
|
79
190
|
/**
|
|
80
|
-
*
|
|
191
|
+
* Converts a queue into an array of its values.
|
|
81
192
|
*
|
|
82
|
-
* @param
|
|
83
|
-
* @
|
|
84
|
-
* @returns An updated queue
|
|
193
|
+
* @param queue: The queue to convert
|
|
194
|
+
* @returns An array containing all values from the given queue
|
|
85
195
|
*
|
|
86
|
-
* @since v0.
|
|
87
|
-
* @history v0.2.0: Originally named `enqueue`
|
|
88
|
-
* @history v0.3.2: Deprecated `enqueue` function
|
|
89
|
-
* @history v0.4.0: Removed `enqueue` function
|
|
196
|
+
* @since v0.6.0
|
|
90
197
|
*/
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
198
|
+
provide let toArray = queue => {
|
|
199
|
+
let arr = Array.make(queue.size, None)
|
|
200
|
+
let mut outIndex = 0
|
|
201
|
+
if (queue.tailIndex < queue.headIndex) {
|
|
202
|
+
// Get the first half
|
|
203
|
+
for (let mut i = queue.headIndex; i < Array.length(queue.array); i += 1) {
|
|
204
|
+
arr[outIndex] = queue.array[i]
|
|
205
|
+
outIndex += 1
|
|
206
|
+
}
|
|
207
|
+
// Get the second half
|
|
208
|
+
let endOffset = Array.length(queue.array) - queue.headIndex
|
|
209
|
+
for (let mut i = 0; i < queue.tailIndex; i += 1) {
|
|
210
|
+
arr[outIndex] = queue.array[i]
|
|
211
|
+
outIndex += 1
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
for (let mut i = queue.headIndex; i < queue.tailIndex; i += 1) {
|
|
215
|
+
arr[outIndex] = queue.array[i]
|
|
216
|
+
outIndex += 1
|
|
217
|
+
}
|
|
95
218
|
}
|
|
219
|
+
Array.map(e => {
|
|
220
|
+
match (e) {
|
|
221
|
+
Some(v) => v,
|
|
222
|
+
None => fail "Impossible: empty bucket in Queue.toArray",
|
|
223
|
+
}
|
|
224
|
+
}, arr)
|
|
96
225
|
}
|
|
97
226
|
|
|
98
227
|
/**
|
|
99
|
-
*
|
|
228
|
+
* Creates a queue from an array.
|
|
100
229
|
*
|
|
101
|
-
* @param
|
|
102
|
-
* @returns
|
|
230
|
+
* @param arr: The array to convert
|
|
231
|
+
* @returns A queue containing all values from the array
|
|
103
232
|
*
|
|
104
|
-
* @since v0.
|
|
105
|
-
* @history v0.2.0: Originally named `dequeue`
|
|
106
|
-
* @history v0.3.2: Deprecated `dequeue` function
|
|
107
|
-
* @history v0.4.0: Removed `dequeue` function
|
|
233
|
+
* @since v0.6.0
|
|
108
234
|
*/
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
235
|
+
provide let fromArray = arr => {
|
|
236
|
+
let size = Array.length(arr)
|
|
237
|
+
let contents = if (size == 0) {
|
|
238
|
+
Array.make(16, None)
|
|
239
|
+
} else {
|
|
240
|
+
Array.init(size * 2, i => {
|
|
241
|
+
if (i < size) {
|
|
242
|
+
Some(arr[i])
|
|
243
|
+
} else {
|
|
244
|
+
None
|
|
245
|
+
}
|
|
246
|
+
})
|
|
119
247
|
}
|
|
248
|
+
{ size, array: contents, headIndex: 0, tailIndex: size }
|
|
120
249
|
}
|
|
121
250
|
|
|
122
251
|
/**
|
|
123
|
-
*
|
|
252
|
+
* Checks if two queues are equivalent by value.
|
|
124
253
|
*
|
|
125
|
-
* @param
|
|
126
|
-
* @
|
|
254
|
+
* @param queue1: The first queue to compare
|
|
255
|
+
* @param queue2: The second queue to compare
|
|
256
|
+
* @returns `true` if the queues are equivalent or `false` otherwise
|
|
127
257
|
*
|
|
128
|
-
* @since v0.
|
|
258
|
+
* @since v0.6.0
|
|
129
259
|
*/
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
260
|
+
provide let (==) = (queue1, queue2) => {
|
|
261
|
+
if (queue1.size != queue2.size) return false
|
|
262
|
+
let len1 = Array.length(queue1.array)
|
|
263
|
+
let len2 = Array.length(queue2.array)
|
|
264
|
+
for (let mut i = 0; i < queue1.size; i += 1) {
|
|
265
|
+
// Get the index of element from queue1
|
|
266
|
+
let mut index1 = queue1.headIndex + i
|
|
267
|
+
if (index1 >= len1) index1 -= len1
|
|
268
|
+
// Get the index of element from queue2
|
|
269
|
+
let mut index2 = queue2.headIndex + i
|
|
270
|
+
if (index2 >= len2) index2 -= len2
|
|
271
|
+
|
|
272
|
+
if (queue1.array[index1] != queue2.array[index2]) return false
|
|
273
|
+
}
|
|
274
|
+
return true
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* An immutable queue implementation.
|
|
279
|
+
*/
|
|
280
|
+
provide module Immutable {
|
|
281
|
+
/**
|
|
282
|
+
* An immutable FIFO (first-in-first-out) data structure.
|
|
283
|
+
*/
|
|
284
|
+
abstract record ImmutableQueue<a> {
|
|
285
|
+
forwards: List<a>,
|
|
286
|
+
backwards: List<a>,
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* An empty queue.
|
|
291
|
+
*
|
|
292
|
+
* @since v0.6.0
|
|
293
|
+
* @history v0.5.4: Originally a module root API
|
|
294
|
+
*/
|
|
295
|
+
provide let empty = {
|
|
296
|
+
let empty = { forwards: [], backwards: [] }
|
|
297
|
+
empty
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Checks if the given queue contains any values.
|
|
302
|
+
*
|
|
303
|
+
* @param queue: The queue to check
|
|
304
|
+
* @returns `true` if the given queue is empty or `false` otherwise
|
|
305
|
+
*
|
|
306
|
+
* @since v0.6.0
|
|
307
|
+
* @history v0.2.0: Originally a module root API
|
|
308
|
+
*/
|
|
309
|
+
provide let isEmpty = queue => {
|
|
310
|
+
match (queue) {
|
|
311
|
+
{ forwards: [], backwards: [] } => true,
|
|
312
|
+
_ => false,
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Returns the value at the beginning of the queue. It is not removed from the queue.
|
|
318
|
+
*
|
|
319
|
+
* @param queue: The queue to inspect
|
|
320
|
+
* @returns `Some(value)` containing the value at the beginning of the queue, or `None` if the queue is empty
|
|
321
|
+
*
|
|
322
|
+
* @since v0.6.0
|
|
323
|
+
* @history v0.2.0: Originally named `head`
|
|
324
|
+
* @history v0.3.2: Deprecated `head` function
|
|
325
|
+
* @history v0.3.2: Originally a module root API
|
|
326
|
+
* @history v0.4.0: Removed `head` function
|
|
327
|
+
*/
|
|
328
|
+
provide let peek = queue => {
|
|
329
|
+
match (queue) {
|
|
330
|
+
{ forwards: [], backwards: [] } => None,
|
|
331
|
+
{ forwards, backwards } => List.head(forwards),
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Adds a value to the end of the queue.
|
|
337
|
+
*
|
|
338
|
+
* @param value: The value to append
|
|
339
|
+
* @param queue: The queue to update
|
|
340
|
+
* @returns An updated queue
|
|
341
|
+
*
|
|
342
|
+
* @since v0.6.0
|
|
343
|
+
* @history v0.2.0: Originally named `enqueue`
|
|
344
|
+
* @history v0.3.2: Deprecated `enqueue` function
|
|
345
|
+
* @history v0.3.2: Originally a module root API
|
|
346
|
+
* @history v0.4.0: Removed `enqueue` function
|
|
347
|
+
*/
|
|
348
|
+
provide let push = (value, queue) => {
|
|
349
|
+
match (queue) {
|
|
350
|
+
{ forwards: [], backwards: [] } => { forwards: [value], backwards: [] },
|
|
351
|
+
{ forwards, backwards } => { forwards, backwards: [value, ...backwards] },
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Dequeues the next value in the queue.
|
|
357
|
+
*
|
|
358
|
+
* @param queue: The queue to change
|
|
359
|
+
* @returns An updated queue
|
|
360
|
+
*
|
|
361
|
+
* @since v0.6.0
|
|
362
|
+
* @history v0.2.0: Originally named `dequeue`
|
|
363
|
+
* @history v0.3.2: Deprecated `dequeue` function
|
|
364
|
+
* @history v0.3.2: Originally a module root API
|
|
365
|
+
* @history v0.4.0: Removed `dequeue` function
|
|
366
|
+
*/
|
|
367
|
+
provide let pop = queue => {
|
|
368
|
+
match (queue) {
|
|
369
|
+
{ forwards: [], backwards: [] } => queue,
|
|
370
|
+
{ forwards: [head], backwards: [] } => { forwards: [], backwards: [] },
|
|
371
|
+
{ forwards: [head], backwards } =>
|
|
372
|
+
{ forwards: List.reverse(backwards), backwards: [] },
|
|
373
|
+
{ forwards: [head, ...ftail], backwards } =>
|
|
374
|
+
{ forwards: ftail, backwards },
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Get the number of values in a queue.
|
|
380
|
+
*
|
|
381
|
+
* @param queue: The queue to inspect
|
|
382
|
+
* @returns The number of values in the queue
|
|
383
|
+
*
|
|
384
|
+
* @since v0.6.0
|
|
385
|
+
* @history v0.3.2: Originally a module root API
|
|
386
|
+
*/
|
|
387
|
+
provide let size = queue => {
|
|
388
|
+
match (queue) {
|
|
389
|
+
{ forwards: [], backwards: [] } => 0,
|
|
390
|
+
{ forwards, backwards: [] } => List.length(forwards),
|
|
391
|
+
{ forwards: [], backwards } => List.length(backwards),
|
|
392
|
+
{ forwards, backwards } => List.length(forwards) + List.length(backwards),
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Converts a queue into a list of its elements.
|
|
398
|
+
*
|
|
399
|
+
* @param queue: The queue to convert
|
|
400
|
+
* @returns A list containing all queue values
|
|
401
|
+
*
|
|
402
|
+
* @since v0.6.0
|
|
403
|
+
*/
|
|
404
|
+
provide let toList = queue => {
|
|
405
|
+
List.append(queue.forwards, List.reverse(queue.backwards))
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Creates a queue from a list.
|
|
410
|
+
*
|
|
411
|
+
* @param list: The list to convert
|
|
412
|
+
* @returns A queue containing all list values
|
|
413
|
+
*
|
|
414
|
+
* @since v0.6.0
|
|
415
|
+
*/
|
|
416
|
+
provide let fromList = list => {
|
|
417
|
+
{ forwards: list, backwards: [] }
|
|
136
418
|
}
|
|
137
419
|
}
|