@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.
Files changed (155) hide show
  1. package/CHANGELOG.md +201 -0
  2. package/LICENSE +1 -1
  3. package/README.md +25 -2
  4. package/array.gr +1512 -199
  5. package/array.md +2032 -94
  6. package/bigint.gr +239 -140
  7. package/bigint.md +450 -106
  8. package/buffer.gr +595 -102
  9. package/buffer.md +903 -145
  10. package/bytes.gr +401 -110
  11. package/bytes.md +551 -63
  12. package/char.gr +228 -49
  13. package/char.md +373 -7
  14. package/exception.gr +26 -12
  15. package/exception.md +29 -5
  16. package/float32.gr +130 -109
  17. package/float32.md +185 -57
  18. package/float64.gr +112 -99
  19. package/float64.md +185 -57
  20. package/hash.gr +62 -40
  21. package/hash.md +27 -3
  22. package/int16.gr +430 -0
  23. package/int16.md +618 -0
  24. package/int32.gr +200 -269
  25. package/int32.md +254 -289
  26. package/int64.gr +142 -225
  27. package/int64.md +254 -289
  28. package/int8.gr +511 -0
  29. package/int8.md +786 -0
  30. package/json.gr +2071 -0
  31. package/json.md +646 -0
  32. package/list.gr +120 -68
  33. package/list.md +125 -80
  34. package/map.gr +560 -57
  35. package/map.md +672 -56
  36. package/marshal.gr +239 -227
  37. package/marshal.md +36 -4
  38. package/number.gr +626 -676
  39. package/number.md +738 -153
  40. package/option.gr +33 -35
  41. package/option.md +58 -42
  42. package/package.json +2 -2
  43. package/path.gr +148 -187
  44. package/path.md +47 -96
  45. package/pervasives.gr +75 -416
  46. package/pervasives.md +85 -180
  47. package/priorityqueue.gr +433 -74
  48. package/priorityqueue.md +422 -54
  49. package/queue.gr +362 -80
  50. package/queue.md +433 -38
  51. package/random.gr +67 -75
  52. package/random.md +68 -40
  53. package/range.gr +135 -63
  54. package/range.md +198 -43
  55. package/rational.gr +284 -0
  56. package/rational.md +545 -0
  57. package/regex.gr +933 -1066
  58. package/regex.md +59 -60
  59. package/result.gr +23 -25
  60. package/result.md +54 -39
  61. package/runtime/atof/common.gr +78 -82
  62. package/runtime/atof/common.md +22 -10
  63. package/runtime/atof/decimal.gr +102 -127
  64. package/runtime/atof/decimal.md +28 -7
  65. package/runtime/atof/lemire.gr +56 -71
  66. package/runtime/atof/lemire.md +9 -1
  67. package/runtime/atof/parse.gr +83 -110
  68. package/runtime/atof/parse.md +12 -2
  69. package/runtime/atof/slow.gr +28 -35
  70. package/runtime/atof/slow.md +9 -1
  71. package/runtime/atof/table.gr +19 -18
  72. package/runtime/atof/table.md +10 -2
  73. package/runtime/atoi/parse.gr +153 -136
  74. package/runtime/atoi/parse.md +50 -1
  75. package/runtime/bigint.gr +410 -517
  76. package/runtime/bigint.md +71 -57
  77. package/runtime/compare.gr +176 -85
  78. package/runtime/compare.md +31 -1
  79. package/runtime/dataStructures.gr +144 -32
  80. package/runtime/dataStructures.md +267 -31
  81. package/runtime/debugPrint.gr +34 -15
  82. package/runtime/debugPrint.md +37 -5
  83. package/runtime/equal.gr +53 -52
  84. package/runtime/equal.md +30 -1
  85. package/runtime/exception.gr +38 -47
  86. package/runtime/exception.md +10 -8
  87. package/runtime/gc.gr +23 -152
  88. package/runtime/gc.md +13 -17
  89. package/runtime/malloc.gr +31 -31
  90. package/runtime/malloc.md +11 -3
  91. package/runtime/numberUtils.gr +193 -174
  92. package/runtime/numberUtils.md +29 -9
  93. package/runtime/numbers.gr +1695 -1021
  94. package/runtime/numbers.md +1098 -134
  95. package/runtime/string.gr +543 -245
  96. package/runtime/string.md +76 -6
  97. package/runtime/unsafe/constants.gr +30 -13
  98. package/runtime/unsafe/constants.md +80 -0
  99. package/runtime/unsafe/conv.gr +55 -28
  100. package/runtime/unsafe/conv.md +41 -9
  101. package/runtime/unsafe/memory.gr +10 -30
  102. package/runtime/unsafe/memory.md +15 -19
  103. package/runtime/unsafe/tags.gr +37 -21
  104. package/runtime/unsafe/tags.md +88 -8
  105. package/runtime/unsafe/wasmf32.gr +30 -36
  106. package/runtime/unsafe/wasmf32.md +64 -56
  107. package/runtime/unsafe/wasmf64.gr +30 -36
  108. package/runtime/unsafe/wasmf64.md +64 -56
  109. package/runtime/unsafe/wasmi32.gr +49 -66
  110. package/runtime/unsafe/wasmi32.md +102 -94
  111. package/runtime/unsafe/wasmi64.gr +52 -79
  112. package/runtime/unsafe/wasmi64.md +108 -100
  113. package/runtime/utils/printing.gr +13 -15
  114. package/runtime/utils/printing.md +11 -3
  115. package/runtime/wasi.gr +294 -295
  116. package/runtime/wasi.md +62 -42
  117. package/set.gr +574 -64
  118. package/set.md +634 -54
  119. package/stack.gr +181 -64
  120. package/stack.md +271 -42
  121. package/string.gr +453 -533
  122. package/string.md +241 -151
  123. package/uint16.gr +369 -0
  124. package/uint16.md +585 -0
  125. package/uint32.gr +470 -0
  126. package/uint32.md +737 -0
  127. package/uint64.gr +471 -0
  128. package/uint64.md +737 -0
  129. package/uint8.gr +369 -0
  130. package/uint8.md +585 -0
  131. package/uri.gr +1093 -0
  132. package/uri.md +477 -0
  133. package/{sys → wasi}/file.gr +914 -500
  134. package/{sys → wasi}/file.md +454 -50
  135. package/wasi/process.gr +292 -0
  136. package/{sys → wasi}/process.md +164 -6
  137. package/wasi/random.gr +77 -0
  138. package/wasi/random.md +80 -0
  139. package/{sys → wasi}/time.gr +15 -22
  140. package/{sys → wasi}/time.md +5 -5
  141. package/immutablearray.gr +0 -929
  142. package/immutablearray.md +0 -1038
  143. package/immutablemap.gr +0 -493
  144. package/immutablemap.md +0 -479
  145. package/immutablepriorityqueue.gr +0 -360
  146. package/immutablepriorityqueue.md +0 -291
  147. package/immutableset.gr +0 -498
  148. package/immutableset.md +0 -449
  149. package/runtime/debug.gr +0 -2
  150. package/runtime/debug.md +0 -6
  151. package/runtime/unsafe/errors.gr +0 -36
  152. package/runtime/unsafe/errors.md +0 -204
  153. package/sys/process.gr +0 -254
  154. package/sys/random.gr +0 -79
  155. package/sys/random.md +0 -66
package/immutablemap.gr DELETED
@@ -1,493 +0,0 @@
1
- /**
2
- * @module ImmutableMap: An ImmutableMap holds key-value pairs. Any value may be used as a key or value. Operations on an ImmutableMap do not mutate the map's internal state.
3
- * @example import ImmutableMap from "immutablemap"
4
- *
5
- * @since v0.5.4
6
- */
7
-
8
- import List from "list"
9
- import Array from "array"
10
- import Option from "option"
11
-
12
- // implementation based on the paper "Implementing Sets Efficiently in a
13
- // Functional Language" by Stephen Adams
14
- record Node<k, v> {
15
- key: k,
16
- val: v,
17
- size: Number,
18
- left: ImmutableMap<k, v>,
19
- right: ImmutableMap<k, v>,
20
- },
21
- /**
22
- * @section Types: Type declarations included in the ImmutableMap module.
23
- */
24
- enum ImmutableMap<k, v> {
25
- Empty,
26
- Tree(Node<k, v>),
27
- }
28
-
29
- /**
30
- * @section Values: Functions and constants for working with ImmutableMaps.
31
- */
32
-
33
- // semi-arbitrary value chosen for algorithm for determining when to balance
34
- // trees; no tree can have a left subtree containing this number of times
35
- // more elements than its right subtree or vice versa
36
- let weight = 4
37
-
38
- /**
39
- * An empty map
40
- *
41
- * @since v0.5.4
42
- */
43
- export let empty = Empty
44
-
45
- // returns the key-value pair of the minimum key in a tree
46
- let rec min = node => {
47
- match (node) {
48
- Tree({ key, val, left: Empty, _ }) => (key, val),
49
- Tree({ left, _ }) => min(left),
50
- Empty => fail "Impossible: min of empty element in ImmutableMap",
51
- }
52
- }
53
-
54
- /**
55
- * Provides the count of key-value pairs stored within the map.
56
- *
57
- * @param map: The map to inspect
58
- * @returns The count of key-value pairs in the map
59
- *
60
- * @since v0.5.4
61
- */
62
- export let size = map => {
63
- match (map) {
64
- Empty => 0,
65
- Tree({ size, _ }) => size,
66
- }
67
- }
68
-
69
- /**
70
- * Determines if the map contains no key-value pairs.
71
- *
72
- * @param map: The map to inspect
73
- * @returns `true` if the given map is empty or `false` otherwise
74
- *
75
- * @since v0.5.4
76
- */
77
- export let isEmpty = map => {
78
- match (map) {
79
- Empty => true,
80
- Tree(_) => false,
81
- }
82
- }
83
-
84
- let unwrapTree = node => {
85
- match (node) {
86
- Empty => fail "Impossible: ImmutableMap unwrapTree got an empty tree node",
87
- Tree(tree) => tree,
88
- }
89
- }
90
-
91
- // helper function for creating a tree node with correct size from
92
- // two balanced trees
93
- let makeNode = (key, val, left, right) => {
94
- Tree({ key, val, size: 1 + size(left) + size(right), left, right })
95
- }
96
-
97
- // note: see Figure 1 of paper referenced above for visual illustration of
98
- // the rotations below
99
-
100
- // node rotation moving the left subtree of the right node to the left side
101
- let singleL = (key, val, left, right) => {
102
- let { key: rKey, val: rVal, left: rl, right: rr, _ } = unwrapTree(right)
103
- makeNode(rKey, rVal, makeNode(key, val, left, rl), rr)
104
- }
105
-
106
- // node rotation moving left child of right tree to the root
107
- let doubleL = (key, val, left, right) => {
108
- let { key: rKey, val: rVal, left: rl, right: rr, _ } = unwrapTree(right)
109
- let { key: rlKey, val: rlVal, left: rll, right: rlr, _ } = unwrapTree(rl)
110
- makeNode(
111
- rlKey,
112
- rlVal,
113
- makeNode(key, val, left, rll),
114
- makeNode(rKey, rVal, rlr, rr)
115
- )
116
- }
117
-
118
- // node rotation moving the right subtree of the left node to the right side
119
- let singleR = (key, val, left, right) => {
120
- let { key: lKey, val: lVal, left: ll, right: lr, _ } = unwrapTree(left)
121
- makeNode(lKey, lVal, ll, makeNode(key, val, lr, right))
122
- }
123
-
124
- // node rotation moving right child of left tree to the root
125
- let doubleR = (key, val, left, right) => {
126
- let { key: lKey, val: lVal, left: ll, right: lr, _ } = unwrapTree(left)
127
- let { key: lrKey, val: lrVal, left: lrl, right: lrr, _ } = unwrapTree(lr)
128
- makeNode(
129
- lrKey,
130
- lrVal,
131
- makeNode(lKey, lVal, ll, lrl),
132
- makeNode(key, val, lrr, right)
133
- )
134
- }
135
-
136
- // creates a new node after either the left or right trees have just had an
137
- // element inserted or removed from them, maintaining balance in the tree
138
- let balancedNode = (key, val, left, right) => {
139
- let makeNodeFn = if (size(left) + size(right) < 2) {
140
- makeNode
141
- } else if (size(right) > weight * size(left)) {
142
- // if the right tree is too much larger than the left then move part of
143
- // the right tree to the left side
144
- let { left: rl, right: rr, _ } = unwrapTree(right)
145
- if (size(rl) < size(rr)) singleL else doubleL
146
- } else if (size(left) > weight * size(right)) {
147
- // if the left tree is too much larger than the right then move part of
148
- // the left tree to the right side
149
- let { left: ll, right: lr, _ } = unwrapTree(left)
150
- if (size(lr) < size(ll)) singleR else doubleR
151
- } else {
152
- // if neither tree is too much larger than the other then simply create
153
- // a new node
154
- makeNode
155
- }
156
-
157
- makeNodeFn(key, val, left, right)
158
- }
159
-
160
- /**
161
- * Produces a new map containing a new key-value pair. If the key already exists in the map, the value is replaced.
162
- *
163
- * @param key: The unique key in the map
164
- * @param value: The value to store
165
- * @param map: The base map
166
- * @returns A new map containing the new key-value pair
167
- *
168
- * @since v0.5.4
169
- */
170
- export let rec set = (key, val, map) => {
171
- match (map) {
172
- Empty => Tree({ key, val, size: 1, left: Empty, right: Empty }),
173
- Tree({ key: nodeKey, val: nodeVal, left, right, _ }) => {
174
- match (compare(key, nodeKey)) {
175
- cmp when cmp < 0 =>
176
- balancedNode(nodeKey, nodeVal, set(key, val, left), right),
177
- cmp when cmp > 0 =>
178
- balancedNode(nodeKey, nodeVal, left, set(key, val, right)),
179
- _ => makeNode(key, val, left, right),
180
- }
181
- },
182
- }
183
- }
184
-
185
- /**
186
- * Retrieves the value for the given key.
187
- *
188
- * @param key: The key to access
189
- * @param map: The map to access
190
- * @returns `Some(value)` if the key exists in the map or `None` otherwise
191
- *
192
- * @since v0.5.4
193
- */
194
- export let rec get = (key, map) => {
195
- match (map) {
196
- Empty => None,
197
- Tree({ key: nodeKey, val: nodeVal, left, right, _ }) => {
198
- match (compare(key, nodeKey)) {
199
- cmp when cmp < 0 => get(key, left),
200
- cmp when cmp > 0 => get(key, right),
201
- _ => Some(nodeVal),
202
- }
203
- },
204
- }
205
- }
206
-
207
- /**
208
- * Determines if the map contains the given key. In such a case, it will always contain a value for the given key.
209
- *
210
- * @param key: The key to search for
211
- * @param map: The map to search
212
- * @returns `true` if the map contains the given key or `false` otherwise
213
- *
214
- * @since v0.5.4
215
- */
216
- export let rec contains = (key, map) => {
217
- Option.isSome(get(key, map))
218
- }
219
-
220
- // removes the minimum element from a tree
221
- let rec removeMin = node => {
222
- match (node) {
223
- Tree({ left: Empty, right, _ }) => right,
224
- Tree({ key, val, left, right, _ }) =>
225
- balancedNode(key, val, removeMin(left), right),
226
- _ => fail "Impossible: ImmutableMap removeMin on empty node",
227
- }
228
- }
229
-
230
- // helper function for removing a node by creating a new node containing the
231
- // removed node's left and right subtrees
232
- let removeInner = (left, right) => {
233
- match ((left, right)) {
234
- (Empty, node) | (node, Empty) => node,
235
- (left, right) => {
236
- let (minKey, minVal) = min(right)
237
- balancedNode(minKey, minVal, left, removeMin(right))
238
- },
239
- }
240
- }
241
-
242
- /**
243
- * Produces a new map without the key-value pair corresponding to the given
244
- * key. If the key doesn't exist in the map, the map will be returned unmodified.
245
- *
246
- * @param key: The key to exclude
247
- * @param map: The map to exclude from
248
- * @returns A new map without the given key
249
- *
250
- * @since v0.5.4
251
- */
252
- export let rec remove = (key, map) => {
253
- match (map) {
254
- Empty => Empty,
255
- Tree({ key: nodeKey, val: nodeVal, left, right, _ }) => {
256
- match (compare(key, nodeKey)) {
257
- cmp when cmp < 0 =>
258
- balancedNode(nodeKey, nodeVal, remove(key, left), right),
259
- cmp when cmp > 0 =>
260
- balancedNode(nodeKey, nodeVal, left, remove(key, right)),
261
- _ => removeInner(left, right),
262
- }
263
- },
264
- }
265
- }
266
-
267
- /**
268
- * Produces a new map by calling an updater function that receives the
269
- * previously stored value as an `Option` and returns the new value to be
270
- * stored as an `Option`. If the key didn't exist previously, the value
271
- * will be `None`. If `None` is returned from the updater function, the
272
- * key-value pair is excluded.
273
- *
274
- * @param key: The unique key in the map
275
- * @param fn: The updater function
276
- * @param map: The base map
277
- * @returns A new map with the value at the given key modified according to the function's output
278
- *
279
- * @since v0.5.4
280
- */
281
- export let update = (key, fn, map) => {
282
- let val = get(key, map)
283
- match (fn(val)) {
284
- Some(next) => set(key, next, map),
285
- None => remove(key, map),
286
- }
287
- }
288
-
289
- /**
290
- * Iterates the map, calling an iterator function with each key and value.
291
- *
292
- * @param fn: The iterator function to call with each key and value
293
- * @param map: The map to iterate
294
- *
295
- * @since v0.5.4
296
- */
297
- export let forEach = (fn, map) => {
298
- let rec forEachInner = node => {
299
- match (node) {
300
- Empty => void,
301
- Tree({ key, val, left, right, _ }) => {
302
- forEachInner(left)
303
- fn(key, val): Void
304
- forEachInner(right)
305
- },
306
- }
307
- }
308
- forEachInner(map)
309
- }
310
-
311
- /**
312
- * Combines all key-value pairs of a map using a reducer function.
313
- *
314
- * @param fn: The reducer function to call on each key and value, where the value returned will be the next accumulator value
315
- * @param init: The initial value to use for the accumulator on the first iteration
316
- * @param map: The map to iterate
317
- * @returns The final accumulator returned from `fn`
318
- *
319
- * @since v0.5.4
320
- */
321
- export let reduce = (fn, init, map) => {
322
- let rec reduceInner = (acc, node) => {
323
- match (node) {
324
- Empty => acc,
325
- Tree({ key, val, left, right, _ }) => {
326
- let newAcc = fn(reduceInner(acc, left), key, val)
327
- reduceInner(newAcc, right)
328
- },
329
- }
330
- }
331
- reduceInner(init, map)
332
- }
333
-
334
- // joins two trees with a value, preserving the BST property of left children
335
- // being less the node and right children being greater than the node
336
- let rec concat3 = (key, val, left, right) => {
337
- match ((left, right)) {
338
- (Empty, node) | (node, Empty) => set(key, val, node),
339
- (Tree(left) as leftOpt, Tree(right) as rightOpt) => {
340
- if (weight * left.size < right.size) {
341
- balancedNode(
342
- right.key,
343
- right.val,
344
- concat3(key, val, leftOpt, right.left),
345
- right.right
346
- )
347
- } else if (weight * right.size < left.size) {
348
- balancedNode(
349
- left.key,
350
- left.val,
351
- left.left,
352
- concat3(key, val, left.right, rightOpt)
353
- )
354
- } else {
355
- makeNode(key, val, leftOpt, rightOpt)
356
- }
357
- },
358
- }
359
- }
360
-
361
- // concatenates two trees of arbitrary size
362
- let concat = (node1, node2) => {
363
- match (node2) {
364
- Empty => node1,
365
- _ => {
366
- let (minKey, minVal) = min(node2)
367
- concat3(minKey, minVal, node1, removeMin(node2))
368
- },
369
- }
370
- }
371
-
372
- let reduceRight = (fn, init, map) => {
373
- let rec reduceInner = (acc, node) => {
374
- match (node) {
375
- Empty => acc,
376
- Tree({ key, val, left, right, _ }) => {
377
- let newAcc = fn(reduceInner(acc, right), key, val)
378
- reduceInner(newAcc, left)
379
- },
380
- }
381
- }
382
- reduceInner(init, map)
383
- }
384
-
385
- /**
386
- * Enumerates all keys in the given map.
387
- *
388
- * @param map: The map to enumerate
389
- * @returns A list containing all keys from the given map
390
- *
391
- * @since v0.5.4
392
- */
393
- export let keys = map => {
394
- reduceRight((list, key, _) => [key, ...list], [], map)
395
- }
396
-
397
- /**
398
- * Enumerates all values in the given map.
399
- *
400
- * @param map: The map to enumerate
401
- * @returns A list containing all values from the given map
402
- *
403
- * @since v0.5.4
404
- */
405
- export let values = map => {
406
- reduceRight((list, _, value) => [value, ...list], [], map)
407
- }
408
-
409
- /**
410
- * Produces a new map excluding the key-value pairs where a predicate function returns `false`.
411
- *
412
- * @param fn: The predicate function to indicate which key-value pairs to exclude from the map, where returning `false` indicates the key-value pair should be excluded
413
- * @param map: The map to iterate
414
- * @returns A new map excluding the key-value pairs not fulfilling the predicate
415
- *
416
- * @since v0.5.4
417
- */
418
- export let filter = (fn, map) => {
419
- let rec filterInner = node => {
420
- match (node) {
421
- Empty => Empty,
422
- Tree({ key, val, left, right, _ }) => {
423
- if (fn(key, val)) {
424
- concat3(key, val, filterInner(left), filterInner(right))
425
- } else {
426
- concat(filterInner(left), filterInner(right))
427
- }
428
- },
429
- }
430
- }
431
- filterInner(map)
432
- }
433
-
434
- /**
435
- * Produces a new map excluding the key-value pairs where a predicate function returns `true`.
436
- *
437
- * @param fn: The predicate function to indicate which key-value pairs to exclude from the map, where returning `true` indicates the key-value pair should be excluded
438
- * @param map: The map to iterate
439
- * @returns A new map excluding the key-value pairs fulfilling the predicate
440
- *
441
- * @since v0.5.4
442
- */
443
- export let reject = (fn, map) => {
444
- filter((key, val) => !fn(key, val), map)
445
- }
446
-
447
- /**
448
- * Creates a map from a list.
449
- *
450
- * @param list: The list to convert
451
- * @returns A map containing all key-value pairs from the list
452
- *
453
- * @since v0.5.4
454
- */
455
- export let fromList = list => {
456
- List.reduce((map, (key, val)) => set(key, val, map), empty, list)
457
- }
458
-
459
- /**
460
- * Enumerates all key-value pairs in the given map.
461
- *
462
- * @param map: The map to enumerate
463
- * @returns A list containing all key-value pairs from the given map
464
- *
465
- * @since v0.5.4
466
- */
467
- export let toList = map => {
468
- reduceRight((list, key, val) => [(key, val), ...list], [], map)
469
- }
470
-
471
- /**
472
- * Creates a map from an array.
473
- *
474
- * @param array: The array to convert
475
- * @returns A map containing all key-value pairs from the array
476
- *
477
- * @since v0.5.4
478
- */
479
- export let fromArray = array => {
480
- Array.reduce((map, (key, val)) => set(key, val, map), empty, array)
481
- }
482
-
483
- /**
484
- * Converts a map into an array of its key-value pairs.
485
- *
486
- * @param map: The map to convert
487
- * @returns An array containing all key-value pairs from the given map
488
- *
489
- * @since v0.5.4
490
- */
491
- export let toArray = map => {
492
- Array.fromList(toList(map))
493
- }