@grain/stdlib 0.4.4 → 0.5.0
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 +87 -0
- package/LICENSE +1 -1
- package/array.gr +92 -73
- package/array.md +18 -18
- package/bigint.gr +497 -0
- package/bigint.md +811 -0
- package/buffer.gr +56 -217
- package/buffer.md +24 -17
- package/bytes.gr +103 -205
- package/bytes.md +19 -0
- package/char.gr +152 -166
- package/char.md +200 -0
- package/exception.md +6 -0
- package/float32.gr +159 -82
- package/float32.md +315 -0
- package/float64.gr +163 -82
- package/float64.md +315 -0
- package/hash.gr +53 -49
- package/int32.gr +479 -230
- package/int32.md +937 -0
- package/int64.gr +479 -230
- package/int64.md +937 -0
- package/list.gr +530 -116
- package/list.md +1141 -0
- package/map.gr +302 -121
- package/map.md +525 -0
- package/number.gr +51 -57
- package/number.md +37 -3
- package/option.gr +25 -25
- package/option.md +1 -1
- package/package.json +3 -3
- package/pervasives.gr +504 -52
- package/pervasives.md +1116 -0
- package/queue.gr +8 -1
- package/queue.md +10 -0
- package/random.gr +196 -0
- package/random.md +179 -0
- package/range.gr +26 -26
- package/regex.gr +1833 -842
- package/regex.md +11 -11
- package/result.md +1 -1
- package/runtime/bigint.gr +2045 -0
- package/runtime/bigint.md +326 -0
- package/runtime/dataStructures.gr +99 -279
- package/runtime/dataStructures.md +391 -0
- package/runtime/debug.gr +0 -1
- package/runtime/debug.md +6 -0
- package/runtime/equal.gr +40 -37
- package/runtime/equal.md +6 -0
- package/runtime/exception.gr +28 -15
- package/runtime/exception.md +30 -0
- package/runtime/gc.gr +50 -20
- package/runtime/gc.md +36 -0
- package/runtime/malloc.gr +32 -22
- package/runtime/malloc.md +55 -0
- package/runtime/numberUtils.gr +297 -142
- package/runtime/numberUtils.md +54 -0
- package/runtime/numbers.gr +1204 -453
- package/runtime/numbers.md +300 -0
- package/runtime/string.gr +193 -228
- package/runtime/string.md +24 -0
- package/runtime/stringUtils.gr +62 -38
- package/runtime/stringUtils.md +6 -0
- package/runtime/unsafe/constants.gr +17 -0
- package/runtime/unsafe/constants.md +72 -0
- package/runtime/unsafe/conv.gr +10 -10
- package/runtime/unsafe/conv.md +71 -0
- package/runtime/unsafe/errors.md +204 -0
- package/runtime/unsafe/memory.gr +14 -3
- package/runtime/unsafe/memory.md +54 -0
- package/runtime/unsafe/printWasm.gr +4 -4
- package/runtime/unsafe/printWasm.md +24 -0
- package/runtime/unsafe/tags.gr +11 -10
- package/runtime/unsafe/tags.md +120 -0
- package/runtime/unsafe/wasmf32.gr +9 -2
- package/runtime/unsafe/wasmf32.md +168 -0
- package/runtime/unsafe/wasmf64.gr +9 -2
- package/runtime/unsafe/wasmf64.md +168 -0
- package/runtime/unsafe/wasmi32.gr +65 -47
- package/runtime/unsafe/wasmi32.md +282 -0
- package/runtime/unsafe/wasmi64.gr +78 -50
- package/runtime/unsafe/wasmi64.md +300 -0
- package/runtime/utils/printing.gr +62 -0
- package/runtime/utils/printing.md +18 -0
- package/runtime/wasi.gr +200 -46
- package/runtime/wasi.md +839 -0
- package/set.gr +125 -121
- package/set.md +24 -21
- package/stack.gr +29 -29
- package/stack.md +4 -6
- package/string.gr +434 -415
- package/string.md +3 -3
- package/sys/file.gr +477 -482
- package/sys/process.gr +33 -47
- package/sys/random.gr +48 -20
- package/sys/random.md +38 -0
- package/sys/time.gr +12 -28
package/set.gr
CHANGED
|
@@ -10,29 +10,34 @@ import { hash } from "hash"
|
|
|
10
10
|
|
|
11
11
|
record Bucket<t> {
|
|
12
12
|
mut key: t,
|
|
13
|
-
mut next: Option<Bucket<t
|
|
13
|
+
mut next: Option<Bucket<t>>,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @section Types: Type declarations included in the Set module.
|
|
18
|
+
*/
|
|
19
|
+
|
|
16
20
|
record Set<k> {
|
|
17
21
|
mut size: Number,
|
|
18
|
-
mut buckets: Array<Option<Bucket<k
|
|
22
|
+
mut buckets: Array<Option<Bucket<k>>>,
|
|
19
23
|
}
|
|
20
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @section Values: Functions for working with Sets.
|
|
27
|
+
*/
|
|
28
|
+
|
|
21
29
|
// TODO: This could take an `eq` function to custom comparisons
|
|
22
30
|
/**
|
|
23
|
-
* Creates a new empty set with an initial storage of the given
|
|
31
|
+
* Creates a new empty set with an initial storage of the given size. As values are added or removed, the internal storage may grow or shrink. Generally, you won't need to care about the storage size of your set and can use `Set.make()` instead.
|
|
24
32
|
*
|
|
25
|
-
* @param
|
|
26
|
-
* @returns An empty set with the given initial storage
|
|
33
|
+
* @param size: The initial storage size of the set
|
|
34
|
+
* @returns An empty set with the given initial storage size
|
|
27
35
|
*
|
|
28
36
|
* @since 0.3.0
|
|
29
37
|
*/
|
|
30
|
-
export let makeSized =
|
|
31
|
-
let buckets = Array.make(
|
|
32
|
-
{
|
|
33
|
-
size: 0,
|
|
34
|
-
buckets
|
|
35
|
-
}
|
|
38
|
+
export let makeSized = size => {
|
|
39
|
+
let buckets = Array.make(size, None)
|
|
40
|
+
{ size: 0, buckets }
|
|
36
41
|
}
|
|
37
42
|
/**
|
|
38
43
|
* Creates a new, empty set.
|
|
@@ -46,8 +51,8 @@ export let make = () => {
|
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
let getBucketIndex = (key, buckets) => {
|
|
49
|
-
let bucketsLength = Array.length(buckets)
|
|
50
|
-
let hashedKey = hash(key)
|
|
54
|
+
let bucketsLength = Array.length(buckets)
|
|
55
|
+
let hashedKey = hash(key)
|
|
51
56
|
hashedKey % bucketsLength
|
|
52
57
|
}
|
|
53
58
|
|
|
@@ -55,45 +60,45 @@ let rec copyNodeWithNewHash = (oldNode, next, tail) => {
|
|
|
55
60
|
match (oldNode) {
|
|
56
61
|
None => void,
|
|
57
62
|
Some(node) => {
|
|
58
|
-
let idx = getBucketIndex(node.key, next)
|
|
59
|
-
let newNode = Some(node)
|
|
63
|
+
let idx = getBucketIndex(node.key, next)
|
|
64
|
+
let newNode = Some(node)
|
|
60
65
|
match (tail[idx]) {
|
|
61
66
|
None => {
|
|
62
|
-
next[idx] = newNode
|
|
67
|
+
next[idx] = newNode
|
|
63
68
|
},
|
|
64
69
|
Some(tailNode) => {
|
|
65
70
|
// If there's already a tail node, we add this to the end
|
|
66
|
-
tailNode.next = newNode
|
|
67
|
-
}
|
|
71
|
+
tailNode.next = newNode
|
|
72
|
+
},
|
|
68
73
|
}
|
|
69
74
|
// Always place this node as the new tail
|
|
70
|
-
tail[idx] = newNode
|
|
75
|
+
tail[idx] = newNode
|
|
71
76
|
// Recurse with the next node
|
|
72
|
-
copyNodeWithNewHash(node.next, next, tail)
|
|
73
|
-
}
|
|
77
|
+
copyNodeWithNewHash(node.next, next, tail)
|
|
78
|
+
},
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
let resize =
|
|
78
|
-
let currentBuckets = set.buckets
|
|
79
|
-
let currentSize = Array.length(currentBuckets)
|
|
80
|
-
let nextSize = currentSize * 2
|
|
82
|
+
let resize = set => {
|
|
83
|
+
let currentBuckets = set.buckets
|
|
84
|
+
let currentSize = Array.length(currentBuckets)
|
|
85
|
+
let nextSize = currentSize * 2
|
|
81
86
|
if (nextSize >= currentSize) {
|
|
82
|
-
let nextBuckets = Array.make(nextSize, None)
|
|
87
|
+
let nextBuckets = Array.make(nextSize, None)
|
|
83
88
|
// This tracks the tail nodes so we can set their `next` to None
|
|
84
|
-
let tailNodes = Array.make(nextSize, None)
|
|
85
|
-
set.buckets = nextBuckets
|
|
86
|
-
Array.forEach(
|
|
87
|
-
copyNodeWithNewHash(old, nextBuckets, tailNodes)
|
|
88
|
-
}, currentBuckets)
|
|
89
|
-
Array.forEach(
|
|
89
|
+
let tailNodes = Array.make(nextSize, None)
|
|
90
|
+
set.buckets = nextBuckets
|
|
91
|
+
Array.forEach(old => {
|
|
92
|
+
copyNodeWithNewHash(old, nextBuckets, tailNodes)
|
|
93
|
+
}, currentBuckets)
|
|
94
|
+
Array.forEach(tail => {
|
|
90
95
|
match (tail) {
|
|
91
96
|
None => void,
|
|
92
97
|
Some(node) => {
|
|
93
|
-
node.next = None
|
|
94
|
-
}
|
|
98
|
+
node.next = None
|
|
99
|
+
},
|
|
95
100
|
}
|
|
96
|
-
}, tailNodes)
|
|
101
|
+
}, tailNodes)
|
|
97
102
|
} else {
|
|
98
103
|
void
|
|
99
104
|
}
|
|
@@ -105,7 +110,7 @@ let rec nodeInBucket = (key, node) => {
|
|
|
105
110
|
} else {
|
|
106
111
|
match (node.next) {
|
|
107
112
|
None => false,
|
|
108
|
-
Some(next) => nodeInBucket(key, next)
|
|
113
|
+
Some(next) => nodeInBucket(key, next),
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
}
|
|
@@ -119,24 +124,24 @@ let rec nodeInBucket = (key, node) => {
|
|
|
119
124
|
* @since 0.3.0
|
|
120
125
|
*/
|
|
121
126
|
export let add = (key, set) => {
|
|
122
|
-
let buckets = set.buckets
|
|
127
|
+
let buckets = set.buckets
|
|
123
128
|
let idx = getBucketIndex(key, buckets)
|
|
124
|
-
let bucket = buckets[idx]
|
|
129
|
+
let bucket = buckets[idx]
|
|
125
130
|
match (bucket) {
|
|
126
131
|
None => {
|
|
127
|
-
buckets[idx] = Some({ key, next: None })
|
|
128
|
-
set.size = incr(set.size)
|
|
132
|
+
buckets[idx] = Some({ key, next: None })
|
|
133
|
+
set.size = incr(set.size)
|
|
129
134
|
},
|
|
130
135
|
Some(node) => {
|
|
131
136
|
if (!nodeInBucket(key, node)) {
|
|
132
|
-
buckets[idx] = Some({ key, next: bucket })
|
|
133
|
-
set.size = incr(set.size)
|
|
134
|
-
}
|
|
135
|
-
}
|
|
137
|
+
buckets[idx] = Some({ key, next: bucket })
|
|
138
|
+
set.size = incr(set.size)
|
|
139
|
+
}
|
|
140
|
+
},
|
|
136
141
|
}
|
|
137
142
|
// Resize if there are more than 2x the amount of nodes as buckets
|
|
138
|
-
if (set.size >
|
|
139
|
-
resize(set)
|
|
143
|
+
if (set.size > Array.length(buckets) * 2) {
|
|
144
|
+
resize(set)
|
|
140
145
|
} else {
|
|
141
146
|
void
|
|
142
147
|
}
|
|
@@ -152,12 +157,12 @@ export let add = (key, set) => {
|
|
|
152
157
|
* @since 0.3.0
|
|
153
158
|
*/
|
|
154
159
|
export let contains = (key, set) => {
|
|
155
|
-
let buckets = set.buckets
|
|
156
|
-
let idx = getBucketIndex(key, buckets)
|
|
157
|
-
let bucket = buckets[idx]
|
|
160
|
+
let buckets = set.buckets
|
|
161
|
+
let idx = getBucketIndex(key, buckets)
|
|
162
|
+
let bucket = buckets[idx]
|
|
158
163
|
match (bucket) {
|
|
159
164
|
None => false,
|
|
160
|
-
Some(node) => nodeInBucket(key, node)
|
|
165
|
+
Some(node) => nodeInBucket(key, node),
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
168
|
|
|
@@ -166,12 +171,12 @@ let rec removeInBucket = (key, node) => {
|
|
|
166
171
|
None => false,
|
|
167
172
|
Some(next) => {
|
|
168
173
|
if (key == next.key) {
|
|
169
|
-
node.next = next.next
|
|
174
|
+
node.next = next.next
|
|
170
175
|
true
|
|
171
176
|
} else {
|
|
172
177
|
removeInBucket(key, next)
|
|
173
178
|
}
|
|
174
|
-
}
|
|
179
|
+
},
|
|
175
180
|
}
|
|
176
181
|
}
|
|
177
182
|
|
|
@@ -184,34 +189,34 @@ let rec removeInBucket = (key, node) => {
|
|
|
184
189
|
* @since 0.3.0
|
|
185
190
|
*/
|
|
186
191
|
export let remove = (key, set) => {
|
|
187
|
-
let buckets = set.buckets
|
|
188
|
-
let idx = getBucketIndex(key, buckets)
|
|
189
|
-
let bucket = buckets[idx]
|
|
192
|
+
let buckets = set.buckets
|
|
193
|
+
let idx = getBucketIndex(key, buckets)
|
|
194
|
+
let bucket = buckets[idx]
|
|
190
195
|
match (bucket) {
|
|
191
196
|
None => void,
|
|
192
197
|
Some(node) => {
|
|
193
198
|
// If it is a top-level node, just replace with next node
|
|
194
199
|
if (key == node.key) {
|
|
195
|
-
set.size = decr(set.size)
|
|
196
|
-
buckets[idx] = node.next
|
|
200
|
+
set.size = decr(set.size)
|
|
201
|
+
buckets[idx] = node.next
|
|
197
202
|
} else {
|
|
198
203
|
if (removeInBucket(key, node)) {
|
|
199
|
-
set.size = decr(set.size)
|
|
204
|
+
set.size = decr(set.size)
|
|
200
205
|
}
|
|
201
206
|
}
|
|
202
|
-
}
|
|
207
|
+
},
|
|
203
208
|
}
|
|
204
209
|
}
|
|
205
210
|
|
|
206
211
|
/**
|
|
207
|
-
*
|
|
212
|
+
* Provides the count of values within the set.
|
|
208
213
|
*
|
|
209
214
|
* @param set: The set to inspect
|
|
210
|
-
* @returns The
|
|
215
|
+
* @returns The count of elements in the set
|
|
211
216
|
*
|
|
212
217
|
* @since 0.3.0
|
|
213
218
|
*/
|
|
214
|
-
export let size =
|
|
219
|
+
export let size = set => {
|
|
215
220
|
set.size
|
|
216
221
|
}
|
|
217
222
|
|
|
@@ -223,7 +228,7 @@ export let size = (set) => {
|
|
|
223
228
|
*
|
|
224
229
|
* @since 0.3.0
|
|
225
230
|
*/
|
|
226
|
-
export let isEmpty =
|
|
231
|
+
export let isEmpty = set => {
|
|
227
232
|
size(set) == 0
|
|
228
233
|
}
|
|
229
234
|
|
|
@@ -234,21 +239,21 @@ export let isEmpty = (set) => {
|
|
|
234
239
|
*
|
|
235
240
|
* @since 0.3.0
|
|
236
241
|
*/
|
|
237
|
-
export let clear =
|
|
238
|
-
set.size = 0
|
|
239
|
-
let buckets = set.buckets
|
|
242
|
+
export let clear = set => {
|
|
243
|
+
set.size = 0
|
|
244
|
+
let buckets = set.buckets
|
|
240
245
|
Array.forEachi((bucket, idx) => {
|
|
241
|
-
buckets[idx] = None
|
|
242
|
-
}, buckets)
|
|
246
|
+
buckets[idx] = None
|
|
247
|
+
}, buckets)
|
|
243
248
|
}
|
|
244
249
|
|
|
245
250
|
let rec forEachBucket = (fn, node) => {
|
|
246
251
|
match (node) {
|
|
247
252
|
None => void,
|
|
248
253
|
Some({ key, next }) => {
|
|
249
|
-
fn(key)
|
|
250
|
-
forEachBucket(fn, next)
|
|
251
|
-
}
|
|
254
|
+
fn(key): Void
|
|
255
|
+
forEachBucket(fn, next)
|
|
256
|
+
},
|
|
252
257
|
}
|
|
253
258
|
}
|
|
254
259
|
|
|
@@ -259,19 +264,19 @@ let rec forEachBucket = (fn, node) => {
|
|
|
259
264
|
* @param set: The set to iterate
|
|
260
265
|
*
|
|
261
266
|
* @since 0.3.0
|
|
267
|
+
* @history v0.5.0: Ensured the iterator function return type is always `Void`
|
|
262
268
|
*/
|
|
263
269
|
export let forEach = (fn, set) => {
|
|
264
|
-
let buckets = set.buckets
|
|
265
|
-
Array.forEach(
|
|
270
|
+
let buckets = set.buckets
|
|
271
|
+
Array.forEach(bucket => {
|
|
266
272
|
forEachBucket(fn, bucket)
|
|
267
|
-
}, buckets)
|
|
273
|
+
}, buckets)
|
|
268
274
|
}
|
|
269
275
|
|
|
270
276
|
let rec reduceEachBucket = (fn, node, acc) => {
|
|
271
277
|
match (node) {
|
|
272
278
|
None => acc,
|
|
273
|
-
Some({ key, next }) =>
|
|
274
|
-
reduceEachBucket(fn, next, fn(acc, key))
|
|
279
|
+
Some({ key, next }) => reduceEachBucket(fn, next, fn(acc, key)),
|
|
275
280
|
}
|
|
276
281
|
}
|
|
277
282
|
|
|
@@ -286,11 +291,11 @@ let rec reduceEachBucket = (fn, node, acc) => {
|
|
|
286
291
|
* @since 0.3.0
|
|
287
292
|
*/
|
|
288
293
|
export let reduce = (fn, init, set) => {
|
|
289
|
-
let buckets = set.buckets
|
|
290
|
-
let mut acc = init
|
|
291
|
-
Array.forEach(
|
|
294
|
+
let buckets = set.buckets
|
|
295
|
+
let mut acc = init
|
|
296
|
+
Array.forEach(bucket => {
|
|
292
297
|
acc = reduceEachBucket(fn, bucket, acc)
|
|
293
|
-
}, buckets)
|
|
298
|
+
}, buckets)
|
|
294
299
|
acc
|
|
295
300
|
}
|
|
296
301
|
|
|
@@ -303,15 +308,14 @@ export let reduce = (fn, init, set) => {
|
|
|
303
308
|
* @since 0.3.0
|
|
304
309
|
*/
|
|
305
310
|
export let filter = (predicate, set) => {
|
|
306
|
-
let keysToRemove = reduce((list, key) =>
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}, keysToRemove);
|
|
311
|
+
let keysToRemove = reduce((list, key) => if (!predicate(key)) {
|
|
312
|
+
[key, ...list]
|
|
313
|
+
} else {
|
|
314
|
+
list
|
|
315
|
+
}, [], set)
|
|
316
|
+
List.forEach(key => {
|
|
317
|
+
remove(key, set)
|
|
318
|
+
}, keysToRemove)
|
|
315
319
|
}
|
|
316
320
|
|
|
317
321
|
/**
|
|
@@ -323,7 +327,7 @@ export let filter = (predicate, set) => {
|
|
|
323
327
|
* @since 0.3.0
|
|
324
328
|
*/
|
|
325
329
|
export let reject = (predicate, set) => {
|
|
326
|
-
filter(
|
|
330
|
+
filter(key => !predicate(key), set)
|
|
327
331
|
}
|
|
328
332
|
|
|
329
333
|
/**
|
|
@@ -334,7 +338,7 @@ export let reject = (predicate, set) => {
|
|
|
334
338
|
*
|
|
335
339
|
* @since 0.3.0
|
|
336
340
|
*/
|
|
337
|
-
export let toList =
|
|
341
|
+
export let toList = set => {
|
|
338
342
|
reduce((list, key) => [key, ...list], [], set)
|
|
339
343
|
}
|
|
340
344
|
|
|
@@ -346,11 +350,11 @@ export let toList = (set) => {
|
|
|
346
350
|
*
|
|
347
351
|
* @since 0.3.0
|
|
348
352
|
*/
|
|
349
|
-
export let fromList =
|
|
350
|
-
let set = make()
|
|
351
|
-
List.forEach(
|
|
352
|
-
add(key, set)
|
|
353
|
-
}, list)
|
|
353
|
+
export let fromList = list => {
|
|
354
|
+
let set = make()
|
|
355
|
+
List.forEach(key => {
|
|
356
|
+
add(key, set)
|
|
357
|
+
}, list)
|
|
354
358
|
set
|
|
355
359
|
}
|
|
356
360
|
|
|
@@ -362,7 +366,7 @@ export let fromList = (list) => {
|
|
|
362
366
|
*
|
|
363
367
|
* @since 0.3.0
|
|
364
368
|
*/
|
|
365
|
-
export let toArray =
|
|
369
|
+
export let toArray = set => {
|
|
366
370
|
Array.fromList(toList(set))
|
|
367
371
|
}
|
|
368
372
|
|
|
@@ -374,11 +378,11 @@ export let toArray = (set) => {
|
|
|
374
378
|
*
|
|
375
379
|
* @since 0.3.0
|
|
376
380
|
*/
|
|
377
|
-
export let fromArray =
|
|
378
|
-
let set = make()
|
|
379
|
-
Array.forEach(
|
|
380
|
-
add(key, set)
|
|
381
|
-
}, array)
|
|
381
|
+
export let fromArray = array => {
|
|
382
|
+
let set = make()
|
|
383
|
+
Array.forEach(key => {
|
|
384
|
+
add(key, set)
|
|
385
|
+
}, array)
|
|
382
386
|
set
|
|
383
387
|
}
|
|
384
388
|
|
|
@@ -392,13 +396,13 @@ export let fromArray = (array) => {
|
|
|
392
396
|
* @since 0.3.0
|
|
393
397
|
*/
|
|
394
398
|
export let union = (set1, set2) => {
|
|
395
|
-
let set = make()
|
|
396
|
-
forEach(
|
|
397
|
-
add(key, set)
|
|
399
|
+
let set = make()
|
|
400
|
+
forEach(key => {
|
|
401
|
+
add(key, set)
|
|
398
402
|
}, set1)
|
|
399
|
-
forEach(
|
|
400
|
-
add(key, set)
|
|
401
|
-
}, set2)
|
|
403
|
+
forEach(key => {
|
|
404
|
+
add(key, set)
|
|
405
|
+
}, set2)
|
|
402
406
|
set
|
|
403
407
|
}
|
|
404
408
|
|
|
@@ -412,17 +416,17 @@ export let union = (set1, set2) => {
|
|
|
412
416
|
* @since 0.3.0
|
|
413
417
|
*/
|
|
414
418
|
export let diff = (set1, set2) => {
|
|
415
|
-
let set = make()
|
|
416
|
-
forEach(
|
|
419
|
+
let set = make()
|
|
420
|
+
forEach(key => {
|
|
417
421
|
if (!contains(key, set2)) {
|
|
418
|
-
add(key, set)
|
|
422
|
+
add(key, set)
|
|
419
423
|
}
|
|
420
424
|
}, set1)
|
|
421
|
-
forEach(
|
|
425
|
+
forEach(key => {
|
|
422
426
|
if (!contains(key, set1)) {
|
|
423
|
-
add(key, set)
|
|
427
|
+
add(key, set)
|
|
424
428
|
}
|
|
425
|
-
}, set2)
|
|
429
|
+
}, set2)
|
|
426
430
|
set
|
|
427
431
|
}
|
|
428
432
|
|
|
@@ -436,17 +440,17 @@ export let diff = (set1, set2) => {
|
|
|
436
440
|
* @since 0.3.0
|
|
437
441
|
*/
|
|
438
442
|
export let intersect = (set1, set2) => {
|
|
439
|
-
let set = make()
|
|
440
|
-
forEach(
|
|
443
|
+
let set = make()
|
|
444
|
+
forEach(key => {
|
|
441
445
|
if (contains(key, set2)) {
|
|
442
|
-
add(key, set)
|
|
446
|
+
add(key, set)
|
|
443
447
|
}
|
|
444
448
|
}, set1)
|
|
445
|
-
forEach(
|
|
449
|
+
forEach(key => {
|
|
446
450
|
if (contains(key, set1)) {
|
|
447
|
-
add(key, set)
|
|
451
|
+
add(key, set)
|
|
448
452
|
}
|
|
449
|
-
}, set2)
|
|
453
|
+
}, set2)
|
|
450
454
|
set
|
|
451
455
|
}
|
|
452
456
|
|
|
@@ -460,6 +464,6 @@ export let intersect = (set1, set2) => {
|
|
|
460
464
|
*
|
|
461
465
|
* @since 0.3.0
|
|
462
466
|
*/
|
|
463
|
-
export let getInternalStats =
|
|
467
|
+
export let getInternalStats = set => {
|
|
464
468
|
(set.size, Array.length(set.buckets))
|
|
465
469
|
}
|
package/set.md
CHANGED
|
@@ -13,24 +13,20 @@ No other changes yet.
|
|
|
13
13
|
import Set from "set"
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Types
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
record Bucket<t> {
|
|
20
|
-
key: t,
|
|
21
|
-
next: Option<Bucket<t>>,
|
|
22
|
-
}
|
|
23
|
-
```
|
|
18
|
+
Type declarations included in the Set module.
|
|
24
19
|
|
|
25
20
|
### Set.**Set**
|
|
26
21
|
|
|
27
22
|
```grain
|
|
28
|
-
|
|
29
|
-
size: Number,
|
|
30
|
-
buckets: Array<Option<Bucket<k>>>,
|
|
31
|
-
}
|
|
23
|
+
type Set<k>
|
|
32
24
|
```
|
|
33
25
|
|
|
26
|
+
## Values
|
|
27
|
+
|
|
28
|
+
Functions for working with Sets.
|
|
29
|
+
|
|
34
30
|
### Set.**makeSized**
|
|
35
31
|
|
|
36
32
|
<details disabled>
|
|
@@ -42,19 +38,19 @@ No other changes yet.
|
|
|
42
38
|
makeSized : Number -> Set<a>
|
|
43
39
|
```
|
|
44
40
|
|
|
45
|
-
Creates a new empty set with an initial storage of the given
|
|
41
|
+
Creates a new empty set with an initial storage of the given size. As values are added or removed, the internal storage may grow or shrink. Generally, you won't need to care about the storage size of your set and can use `Set.make()` instead.
|
|
46
42
|
|
|
47
43
|
Parameters:
|
|
48
44
|
|
|
49
45
|
|param|type|description|
|
|
50
46
|
|-----|----|-----------|
|
|
51
|
-
|`
|
|
47
|
+
|`size`|`Number`|The initial storage size of the set|
|
|
52
48
|
|
|
53
49
|
Returns:
|
|
54
50
|
|
|
55
51
|
|type|description|
|
|
56
52
|
|----|-----------|
|
|
57
|
-
|`Set<a>`|An empty set with the given initial storage
|
|
53
|
+
|`Set<a>`|An empty set with the given initial storage size|
|
|
58
54
|
|
|
59
55
|
### Set.**make**
|
|
60
56
|
|
|
@@ -152,7 +148,7 @@ No other changes yet.
|
|
|
152
148
|
size : Set<a> -> Number
|
|
153
149
|
```
|
|
154
150
|
|
|
155
|
-
|
|
151
|
+
Provides the count of values within the set.
|
|
156
152
|
|
|
157
153
|
Parameters:
|
|
158
154
|
|
|
@@ -164,7 +160,7 @@ Returns:
|
|
|
164
160
|
|
|
165
161
|
|type|description|
|
|
166
162
|
|----|-----------|
|
|
167
|
-
|`Number`|The
|
|
163
|
+
|`Number`|The count of elements in the set|
|
|
168
164
|
|
|
169
165
|
### Set.**isEmpty**
|
|
170
166
|
|
|
@@ -212,13 +208,20 @@ Parameters:
|
|
|
212
208
|
|
|
213
209
|
### Set.**forEach**
|
|
214
210
|
|
|
215
|
-
<details
|
|
216
|
-
<summary
|
|
217
|
-
|
|
211
|
+
<details>
|
|
212
|
+
<summary>Added in <code>0.3.0</code></summary>
|
|
213
|
+
<table>
|
|
214
|
+
<thead>
|
|
215
|
+
<tr><th>version</th><th>changes</th></tr>
|
|
216
|
+
</thead>
|
|
217
|
+
<tbody>
|
|
218
|
+
<tr><td><code>next</code></td><td>Ensured the iterator function return type is always `Void`</td></tr>
|
|
219
|
+
</tbody>
|
|
220
|
+
</table>
|
|
218
221
|
</details>
|
|
219
222
|
|
|
220
223
|
```grain
|
|
221
|
-
forEach : ((a ->
|
|
224
|
+
forEach : ((a -> Void), Set<a>) -> Void
|
|
222
225
|
```
|
|
223
226
|
|
|
224
227
|
Iterates the set, calling an iterator function on each element.
|
|
@@ -227,7 +230,7 @@ Parameters:
|
|
|
227
230
|
|
|
228
231
|
|param|type|description|
|
|
229
232
|
|-----|----|-----------|
|
|
230
|
-
|`fn`|`a ->
|
|
233
|
+
|`fn`|`a -> Void`|The iterator function to call with each element|
|
|
231
234
|
|`set`|`Set<a>`|The set to iterate|
|
|
232
235
|
|
|
233
236
|
### Set.**reduce**
|
package/stack.gr
CHANGED
|
@@ -13,7 +13,7 @@ import List from "list"
|
|
|
13
13
|
* Stacks are immutable data structures that store their data in a List.
|
|
14
14
|
*/
|
|
15
15
|
record Stack<a> {
|
|
16
|
-
|
|
16
|
+
data: List<a>,
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -26,33 +26,33 @@ record Stack<a> {
|
|
|
26
26
|
* @returns An empty stack
|
|
27
27
|
*/
|
|
28
28
|
export let make = () => {
|
|
29
|
-
|
|
29
|
+
{ data: [], }
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Checks if the given stack contains no items.
|
|
34
34
|
*
|
|
35
35
|
* @param stack: The stack to check
|
|
36
|
-
* @returns `true` if the stack has no items
|
|
36
|
+
* @returns `true` if the stack has no items or `false` otherwise
|
|
37
37
|
*/
|
|
38
|
-
export let isEmpty =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
export let isEmpty = stack => {
|
|
39
|
+
match (stack) {
|
|
40
|
+
{ data: [] } => true,
|
|
41
|
+
_ => false,
|
|
42
|
+
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Provides the value at the top of the stack, if it exists.
|
|
47
47
|
*
|
|
48
48
|
* @param stack: The stack to inspect
|
|
49
|
-
* @returns
|
|
49
|
+
* @returns `Some(value)` containing the value at the top of the stack or `None` otherwise.
|
|
50
50
|
*/
|
|
51
|
-
export let peek =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
export let peek = stack => {
|
|
52
|
+
match (stack) {
|
|
53
|
+
{ data: [] } => None,
|
|
54
|
+
{ data } => List.head(data),
|
|
55
|
+
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
@@ -63,10 +63,10 @@ export let peek = (stack) => {
|
|
|
63
63
|
* @returns A new stack with the item added to the end
|
|
64
64
|
*/
|
|
65
65
|
export let push = (value, stack) => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
match (stack) {
|
|
67
|
+
{ data: [] } => { data: [value], },
|
|
68
|
+
{ data } => { data: [value, ...data], },
|
|
69
|
+
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
@@ -75,11 +75,11 @@ export let push = (value, stack) => {
|
|
|
75
75
|
* @param stack: The stack being updated
|
|
76
76
|
* @returns A new stack with the last item removed
|
|
77
77
|
*/
|
|
78
|
-
export let pop =
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
export let pop = stack => {
|
|
79
|
+
match (stack) {
|
|
80
|
+
{ data: [] } => stack,
|
|
81
|
+
{ data: [head, ...tail] } => { data: tail, },
|
|
82
|
+
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
@@ -88,9 +88,9 @@ export let pop = (stack) => {
|
|
|
88
88
|
* @param stack: The stack to inspect
|
|
89
89
|
* @returns The count of the items in the stack
|
|
90
90
|
*/
|
|
91
|
-
export let size =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
export let size = stack => {
|
|
92
|
+
match (stack) {
|
|
93
|
+
{ data: [] } => 0,
|
|
94
|
+
{ data } => List.length(data),
|
|
95
|
+
}
|
|
96
96
|
}
|