@grain/stdlib 0.4.2 → 0.4.6
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 +52 -0
- package/LICENSE +1 -1
- package/array.gr +200 -89
- package/array.md +81 -5
- package/buffer.gr +93 -36
- package/bytes.gr +10 -10
- package/char.gr +112 -56
- package/char.md +200 -0
- package/float32.gr +120 -4
- package/float32.md +315 -0
- package/float64.gr +120 -4
- package/float64.md +315 -0
- package/hash.gr +42 -15
- package/hash.md +44 -0
- package/int32.gr +370 -75
- package/int32.md +833 -0
- package/int64.gr +370 -75
- package/int64.md +833 -0
- package/list.gr +121 -50
- package/map.gr +106 -110
- package/number.gr +37 -1
- package/number.md +66 -0
- package/option.gr +260 -53
- package/option.md +579 -0
- package/package.json +1 -1
- package/pervasives.gr +32 -20
- package/queue.gr +102 -30
- package/queue.md +191 -0
- package/range.gr +26 -26
- package/range.md +1 -1
- package/regex.md +9 -9
- package/result.gr +216 -70
- package/result.md +446 -0
- package/runtime/dataStructures.gr +28 -29
- package/runtime/debug.gr +0 -1
- package/runtime/equal.gr +37 -16
- package/runtime/exception.gr +28 -15
- package/runtime/gc.gr +33 -20
- package/runtime/malloc.gr +19 -11
- package/runtime/numberUtils.gr +208 -103
- package/runtime/numbers.gr +217 -118
- package/runtime/string.gr +98 -39
- package/runtime/stringUtils.gr +176 -0
- package/runtime/unsafe/conv.gr +10 -10
- package/runtime/unsafe/memory.gr +14 -3
- package/runtime/unsafe/printWasm.gr +4 -4
- package/runtime/unsafe/tags.gr +2 -2
- package/runtime/unsafe/wasmf32.gr +9 -2
- package/runtime/unsafe/wasmf64.gr +9 -2
- package/runtime/unsafe/wasmi32.gr +65 -47
- package/runtime/unsafe/wasmi64.gr +78 -50
- package/runtime/wasi.gr +199 -45
- package/set.gr +281 -119
- package/set.md +502 -0
- package/stack.gr +26 -26
- package/string.gr +657 -341
- package/string.md +815 -0
- package/sys/file.gr +356 -177
- package/sys/process.gr +10 -6
- package/sys/random.gr +3 -6
- package/sys/time.gr +3 -3
package/list.gr
CHANGED
|
@@ -16,11 +16,11 @@ let init = (length, fn) => {
|
|
|
16
16
|
iter(0, length)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
let length =
|
|
19
|
+
let length = list => {
|
|
20
20
|
let rec iter = (len, list) => {
|
|
21
21
|
match (list) {
|
|
22
22
|
[] => len,
|
|
23
|
-
[_, ...rest] => iter(len + 1, rest)
|
|
23
|
+
[_, ...rest] => iter(len + 1, rest),
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
iter(0, list)
|
|
@@ -30,17 +30,17 @@ let sum = list => {
|
|
|
30
30
|
let rec iter = (n, list) => {
|
|
31
31
|
match (list) {
|
|
32
32
|
[] => n,
|
|
33
|
-
[first, ...rest] => iter(n + first, rest)
|
|
33
|
+
[first, ...rest] => iter(n + first, rest),
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
iter(0, list)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
let reverse =
|
|
39
|
+
let reverse = list => {
|
|
40
40
|
let rec iter = (list, acc) => {
|
|
41
41
|
match (list) {
|
|
42
42
|
[] => acc,
|
|
43
|
-
[first, ...rest] => iter(rest, [first, ...acc])
|
|
43
|
+
[first, ...rest] => iter(rest, [first, ...acc]),
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
iter(list, [])
|
|
@@ -49,35 +49,35 @@ let reverse = (list) => {
|
|
|
49
49
|
let rec append = (list1, list2) => {
|
|
50
50
|
match (list1) {
|
|
51
51
|
[] => list2,
|
|
52
|
-
[first, ...rest] => [first, ...append(rest, list2)]
|
|
52
|
+
[first, ...rest] => [first, ...append(rest, list2)],
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
let rec contains = (value, list) => {
|
|
57
57
|
match (list) {
|
|
58
58
|
[] => false,
|
|
59
|
-
[first, ...rest] =>
|
|
59
|
+
[first, ...rest] => first == value || contains(value, rest),
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
let rec reduce = (fn, acc, list) => {
|
|
64
64
|
match (list) {
|
|
65
65
|
[] => acc,
|
|
66
|
-
[first, ...rest] => reduce(fn, fn(acc, first), rest)
|
|
66
|
+
[first, ...rest] => reduce(fn, fn(acc, first), rest),
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
let rec reduceRight = (fn, acc, list) => {
|
|
71
71
|
match (list) {
|
|
72
72
|
[] => acc,
|
|
73
|
-
[first, ...rest] => fn(first, reduceRight(fn, acc, rest))
|
|
73
|
+
[first, ...rest] => fn(first, reduceRight(fn, acc, rest)),
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
let rec map = (fn, list) => {
|
|
78
78
|
match (list) {
|
|
79
79
|
[] => [],
|
|
80
|
-
[first, ...rest] => [fn(first), ...map(fn, rest)]
|
|
80
|
+
[first, ...rest] => [fn(first), ...map(fn, rest)],
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -85,7 +85,7 @@ let mapi = (fn, list) => {
|
|
|
85
85
|
let rec iter = (fn, list, index) => {
|
|
86
86
|
match (list) {
|
|
87
87
|
[] => [],
|
|
88
|
-
[first, ...rest] => [fn(first, index), ...iter(fn, rest, index + 1)]
|
|
88
|
+
[first, ...rest] => [fn(first, index), ...iter(fn, rest, index + 1)],
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
iter(fn, list, 0)
|
|
@@ -94,16 +94,20 @@ let mapi = (fn, list) => {
|
|
|
94
94
|
let rec flatMap = (fn, list) => {
|
|
95
95
|
match (list) {
|
|
96
96
|
[] => [],
|
|
97
|
-
[first, ...rest] => append(fn(first), flatMap(fn, rest))
|
|
97
|
+
[first, ...rest] => append(fn(first), flatMap(fn, rest)),
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
let every = (fn, list) => {
|
|
102
|
-
reduce((acc, value) => {
|
|
102
|
+
reduce((acc, value) => {
|
|
103
|
+
acc && fn(value)
|
|
104
|
+
}, true, list)
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
let some = (fn, list) => {
|
|
106
|
-
reduce((acc, value) => {
|
|
108
|
+
reduce((acc, value) => {
|
|
109
|
+
acc || fn(value)
|
|
110
|
+
}, false, list)
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
let rec forEach = (fn, list) => {
|
|
@@ -112,7 +116,7 @@ let rec forEach = (fn, list) => {
|
|
|
112
116
|
[first, ...rest] => {
|
|
113
117
|
fn(first)
|
|
114
118
|
forEach(fn, rest)
|
|
115
|
-
}
|
|
119
|
+
},
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
122
|
|
|
@@ -123,7 +127,7 @@ let forEachi = (fn, list) => {
|
|
|
123
127
|
[first, ...rest] => {
|
|
124
128
|
fn(first, index)
|
|
125
129
|
iter(fn, rest, index + 1)
|
|
126
|
-
}
|
|
130
|
+
},
|
|
127
131
|
}
|
|
128
132
|
}
|
|
129
133
|
iter(fn, list, 0)
|
|
@@ -132,7 +136,8 @@ let forEachi = (fn, list) => {
|
|
|
132
136
|
let rec filter = (fn, list) => {
|
|
133
137
|
match (list) {
|
|
134
138
|
[] => [],
|
|
135
|
-
[first, ...rest] =>
|
|
139
|
+
[first, ...rest] =>
|
|
140
|
+
if (fn(first)) [first, ...filter(fn, rest)] else filter(fn, rest),
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
|
|
@@ -140,7 +145,9 @@ let filteri = (fn, list) => {
|
|
|
140
145
|
let rec iter = (fn, list, index) => {
|
|
141
146
|
match (list) {
|
|
142
147
|
[] => [],
|
|
143
|
-
[first, ...rest] =>
|
|
148
|
+
[first, ...rest] =>
|
|
149
|
+
if (fn(first, index)) [first, ...iter(fn, rest, index + 1)]
|
|
150
|
+
else iter(fn, rest, index + 1),
|
|
144
151
|
}
|
|
145
152
|
}
|
|
146
153
|
iter(fn, list, 0)
|
|
@@ -149,21 +156,22 @@ let filteri = (fn, list) => {
|
|
|
149
156
|
let rec reject = (fn, list) => {
|
|
150
157
|
match (list) {
|
|
151
158
|
[] => [],
|
|
152
|
-
[first, ...rest] =>
|
|
159
|
+
[first, ...rest] =>
|
|
160
|
+
if (!fn(first)) [first, ...reject(fn, rest)] else reject(fn, rest),
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
|
|
156
|
-
let head =
|
|
164
|
+
let head = list => {
|
|
157
165
|
match (list) {
|
|
158
166
|
[] => None,
|
|
159
|
-
[first, ..._] => Some(first)
|
|
167
|
+
[first, ..._] => Some(first),
|
|
160
168
|
}
|
|
161
169
|
}
|
|
162
170
|
|
|
163
|
-
let tail =
|
|
171
|
+
let tail = list => {
|
|
164
172
|
match (list) {
|
|
165
173
|
[] => None,
|
|
166
|
-
[_, ...rest] => Some(rest)
|
|
174
|
+
[_, ...rest] => Some(rest),
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
177
|
|
|
@@ -173,15 +181,15 @@ let rec nth = (index, list) => {
|
|
|
173
181
|
} else {
|
|
174
182
|
match (list) {
|
|
175
183
|
[] => None,
|
|
176
|
-
[first, ...rest] => if (index == 0) Some(first) else nth(index - 1, rest)
|
|
184
|
+
[first, ...rest] => if (index == 0) Some(first) else nth(index - 1, rest),
|
|
177
185
|
}
|
|
178
186
|
}
|
|
179
187
|
}
|
|
180
188
|
|
|
181
|
-
let rec flatten =
|
|
189
|
+
let rec flatten = list => {
|
|
182
190
|
match (list) {
|
|
183
191
|
[] => [],
|
|
184
|
-
[first, ...rest] => append(first, flatten(rest))
|
|
192
|
+
[first, ...rest] => append(first, flatten(rest)),
|
|
185
193
|
}
|
|
186
194
|
}
|
|
187
195
|
|
|
@@ -189,9 +197,11 @@ let rec insert = (value, index, list) => {
|
|
|
189
197
|
if (index < 0) {
|
|
190
198
|
fail "insert index cannot be a negative number"
|
|
191
199
|
} else {
|
|
192
|
-
match(list) {
|
|
200
|
+
match (list) {
|
|
193
201
|
[] => if (index == 0) [value] else fail "insert index is out-of-bounds",
|
|
194
|
-
[first, ...rest] =>
|
|
202
|
+
[first, ...rest] =>
|
|
203
|
+
if (index == 0) [value, ...list]
|
|
204
|
+
else [first, ...insert(value, index - 1, rest)],
|
|
195
205
|
}
|
|
196
206
|
}
|
|
197
207
|
}
|
|
@@ -200,7 +210,7 @@ let count = (fn, list) => {
|
|
|
200
210
|
let rec iter = (n, list) => {
|
|
201
211
|
match (list) {
|
|
202
212
|
[] => n,
|
|
203
|
-
[first, ...rest] => if (fn(first)) iter(n + 1, rest) else iter(n, rest)
|
|
213
|
+
[first, ...rest] => if (fn(first)) iter(n + 1, rest) else iter(n, rest),
|
|
204
214
|
}
|
|
205
215
|
}
|
|
206
216
|
iter(0, list)
|
|
@@ -212,8 +222,11 @@ let part = (count, list) => {
|
|
|
212
222
|
} else {
|
|
213
223
|
let rec iter = (list1, list2, count) => {
|
|
214
224
|
match (list2) {
|
|
215
|
-
[] =>
|
|
216
|
-
|
|
225
|
+
[] =>
|
|
226
|
+
if (count > 0) fail "part count is out-of-bounds" else (list1, list2),
|
|
227
|
+
[first, ...rest] =>
|
|
228
|
+
if (count > 0) iter([first, ...list1], rest, count - 1)
|
|
229
|
+
else (list1, list2),
|
|
217
230
|
}
|
|
218
231
|
}
|
|
219
232
|
let (pt1, pt2) = iter([], list, count)
|
|
@@ -222,15 +235,18 @@ let part = (count, list) => {
|
|
|
222
235
|
}
|
|
223
236
|
|
|
224
237
|
let rotate = (count, list) => {
|
|
225
|
-
let (beginning, end) = if (count >= 0) part(count, list)
|
|
238
|
+
let (beginning, end) = if (count >= 0) part(count, list)
|
|
239
|
+
else part(length(list) + count, list)
|
|
226
240
|
append(end, beginning)
|
|
227
241
|
}
|
|
228
242
|
|
|
229
|
-
let unique =
|
|
243
|
+
let unique = list => {
|
|
230
244
|
let rec iter = (list, acc) => {
|
|
231
245
|
match (list) {
|
|
232
246
|
[] => reverse(acc),
|
|
233
|
-
[first, ...rest] =>
|
|
247
|
+
[first, ...rest] =>
|
|
248
|
+
if (contains(first, acc)) iter(rest, acc)
|
|
249
|
+
else iter(rest, [first, ...acc]),
|
|
234
250
|
}
|
|
235
251
|
}
|
|
236
252
|
iter(list, [])
|
|
@@ -241,9 +257,9 @@ let rec drop = (n, list) => {
|
|
|
241
257
|
fail "number of items to drop cannot be a negative number"
|
|
242
258
|
} else {
|
|
243
259
|
match ((n, list)) {
|
|
244
|
-
(_,[]) => [],
|
|
260
|
+
(_, []) => [],
|
|
245
261
|
(n, _) when n == 0 => list,
|
|
246
|
-
(n, [first, ...rest]) => drop(n - 1, rest)
|
|
262
|
+
(n, [first, ...rest]) => drop(n - 1, rest),
|
|
247
263
|
}
|
|
248
264
|
}
|
|
249
265
|
}
|
|
@@ -251,7 +267,7 @@ let rec drop = (n, list) => {
|
|
|
251
267
|
let rec dropWhile = (fn, list) => {
|
|
252
268
|
match (list) {
|
|
253
269
|
[] => list,
|
|
254
|
-
[first, ...rest] => if (fn(first)) dropWhile(fn, rest) else list
|
|
270
|
+
[first, ...rest] => if (fn(first)) dropWhile(fn, rest) else list,
|
|
255
271
|
}
|
|
256
272
|
}
|
|
257
273
|
|
|
@@ -262,7 +278,7 @@ let rec take = (n, list) => {
|
|
|
262
278
|
match ((n, list)) {
|
|
263
279
|
(_, []) => list,
|
|
264
280
|
(n, _) when n == 0 => [],
|
|
265
|
-
(n, [first, ...rest]) => [first, ...take(n-1, rest)]
|
|
281
|
+
(n, [first, ...rest]) => [first, ...take(n - 1, rest)],
|
|
266
282
|
}
|
|
267
283
|
}
|
|
268
284
|
}
|
|
@@ -270,14 +286,14 @@ let rec take = (n, list) => {
|
|
|
270
286
|
let rec takeWhile = (p, list) => {
|
|
271
287
|
match (list) {
|
|
272
288
|
[] => [],
|
|
273
|
-
[first, ...rest] => if (p(first)) [first, ...takeWhile(p, rest)] else []
|
|
289
|
+
[first, ...rest] => if (p(first)) [first, ...takeWhile(p, rest)] else [],
|
|
274
290
|
}
|
|
275
291
|
}
|
|
276
292
|
|
|
277
293
|
let rec find = (fn, list) => {
|
|
278
294
|
match (list) {
|
|
279
295
|
[] => None,
|
|
280
|
-
[first, ...rest] => if (fn(first)) Some(first) else find(fn, rest)
|
|
296
|
+
[first, ...rest] => if (fn(first)) Some(first) else find(fn, rest),
|
|
281
297
|
}
|
|
282
298
|
}
|
|
283
299
|
|
|
@@ -285,7 +301,8 @@ let findIndex = (fn, list) => {
|
|
|
285
301
|
let rec findItemIndex = (l, index) => {
|
|
286
302
|
match (l) {
|
|
287
303
|
[] => None,
|
|
288
|
-
[first, ...rest] =>
|
|
304
|
+
[first, ...rest] =>
|
|
305
|
+
if (fn(first)) Some(index) else findItemIndex(rest, index + 1),
|
|
289
306
|
}
|
|
290
307
|
}
|
|
291
308
|
findItemIndex(list, 0)
|
|
@@ -293,10 +310,10 @@ let findIndex = (fn, list) => {
|
|
|
293
310
|
|
|
294
311
|
let product = (a, b) => {
|
|
295
312
|
let mut list = []
|
|
296
|
-
forEach(
|
|
297
|
-
forEach(
|
|
298
|
-
|
|
299
|
-
},b)
|
|
313
|
+
forEach(aItem => {
|
|
314
|
+
forEach(bItem => {
|
|
315
|
+
list = [(aItem, bItem), ...list]
|
|
316
|
+
}, b)
|
|
300
317
|
}, a)
|
|
301
318
|
reverse(list)
|
|
302
319
|
}
|
|
@@ -311,21 +328,75 @@ let sub = (start, length, list) => {
|
|
|
311
328
|
// @returns String
|
|
312
329
|
let join = (separator: String, items: List<String>) => {
|
|
313
330
|
let rec iter = (sep, acc, rem) => {
|
|
314
|
-
match(rem) {
|
|
331
|
+
match (rem) {
|
|
315
332
|
[] => acc,
|
|
316
333
|
[hd, ...tl] => {
|
|
317
|
-
let newAcc = match(acc) {
|
|
334
|
+
let newAcc = match (acc) {
|
|
318
335
|
None => Some(hd),
|
|
319
|
-
Some(s) => Some(hd ++ sep ++ s)
|
|
336
|
+
Some(s) => Some(hd ++ sep ++ s),
|
|
320
337
|
}
|
|
321
338
|
iter(sep, newAcc, tl)
|
|
322
|
-
}
|
|
339
|
+
},
|
|
323
340
|
}
|
|
324
341
|
}
|
|
325
342
|
|
|
326
343
|
// Reverse and reduce to take advantage of TCE
|
|
327
|
-
match(iter(separator, None, reverse(items))) {
|
|
344
|
+
match (iter(separator, None, reverse(items))) {
|
|
328
345
|
None => "",
|
|
329
346
|
Some(s) => s,
|
|
330
347
|
}
|
|
331
348
|
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Reverses the first list and appends the second list to the end.
|
|
352
|
+
*
|
|
353
|
+
* @param list1: The list to reverse
|
|
354
|
+
* @param list2: The list to append
|
|
355
|
+
* @since v0.4.5
|
|
356
|
+
*/
|
|
357
|
+
let rec revAppend = (list1, list2) => {
|
|
358
|
+
match (list1) {
|
|
359
|
+
[hd, ...tl] => revAppend(tl, [hd, ...list2]),
|
|
360
|
+
[] => list2,
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Sorts the given list based on a given comparator function. The resulting list is sorted in increasing order.
|
|
366
|
+
*
|
|
367
|
+
* Ordering is calculated using a comparator function which takes two list elements and must return 0 if both are equal, a positive number if the first is greater, and a negative number if the first is smaller.
|
|
368
|
+
* @param comp: The comparator function used to indicate sort order
|
|
369
|
+
* @param list: The list to be sorted
|
|
370
|
+
* @since v0.4.5
|
|
371
|
+
*/
|
|
372
|
+
let sort = (comp, list) => {
|
|
373
|
+
let rec merge = (left, right, list) => {
|
|
374
|
+
match ((left, right)) {
|
|
375
|
+
(_, []) => {
|
|
376
|
+
revAppend(list, left)
|
|
377
|
+
},
|
|
378
|
+
([], _) => {
|
|
379
|
+
revAppend(list, right)
|
|
380
|
+
},
|
|
381
|
+
([lhd, ...ltl], [rhd, ...rtl]) => {
|
|
382
|
+
if (comp(lhd, rhd) < 0) {
|
|
383
|
+
merge(ltl, right, append([lhd], list))
|
|
384
|
+
} else {
|
|
385
|
+
merge(left, rtl, append([rhd], list))
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
let rec mergesort = list => {
|
|
392
|
+
if (length(list) <= 1) {
|
|
393
|
+
list
|
|
394
|
+
} else {
|
|
395
|
+
let middle = length(list) / 2
|
|
396
|
+
let (left, right) = part(middle, list)
|
|
397
|
+
merge(mergesort(left), mergesort(right), [])
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
mergesort(list)
|
|
402
|
+
}
|