@grain/stdlib 0.5.12 → 0.6.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.
Files changed (155) hide show
  1. package/CHANGELOG.md +200 -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 +47 -37
  21. package/hash.md +21 -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 +2084 -0
  31. package/json.md +608 -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 +191 -172
  92. package/runtime/numberUtils.md +17 -9
  93. package/runtime/numbers.gr +1695 -1021
  94. package/runtime/numbers.md +1098 -134
  95. package/runtime/string.gr +540 -242
  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/list.gr CHANGED
@@ -1,16 +1,13 @@
1
1
  /**
2
- * @module List: Utilities for working with lists.
2
+ * Utilities for working with lists.
3
3
  *
4
- * @example import List from "list"
4
+ * @example from "list" include List
5
5
  *
6
6
  * @since v0.2.0
7
7
  * @history v0.1.0: Originally named `lists`
8
8
  * @history v0.2.0: Renamed to `list`
9
9
  */
10
-
11
- /**
12
- * @section Values: Functions for working with the List data type.
13
- */
10
+ module List
14
11
 
15
12
  /**
16
13
  * Creates a new list of the specified length where each element is
@@ -25,7 +22,7 @@
25
22
  *
26
23
  * @since v0.3.0
27
24
  */
28
- export let init = (length, fn) => {
25
+ provide let init = (length, fn) => {
29
26
  // This method can be further improved by checking the length against a specific size
30
27
  // and determining if it can be made tail-recursive, then use List.reverse on it.
31
28
  // Which would be the same as OCaml does it in https://github.com/ocaml/ocaml/blob/03839754f46319aa36d9dad56940a6f3c3bcb48a/stdlib/list.ml#L79
@@ -48,7 +45,7 @@ export let init = (length, fn) => {
48
45
  * @since v0.1.0
49
46
  * @history v0.2.0: Made the function tail-recursive
50
47
  */
51
- export let length = list => {
48
+ provide let length = list => {
52
49
  let rec iter = (len, list) => {
53
50
  match (list) {
54
51
  [] => len,
@@ -58,6 +55,21 @@ export let length = list => {
58
55
  iter(0, list)
59
56
  }
60
57
 
58
+ /**
59
+ * Determines if the list contains no elements.
60
+ *
61
+ * @param list: The list to inspect
62
+ * @returns `true` if the list is empty and `false` otherwise
63
+ *
64
+ * @since v0.6.0
65
+ */
66
+ provide let isEmpty = list => {
67
+ match (list) {
68
+ [] => true,
69
+ _ => false,
70
+ }
71
+ }
72
+
61
73
  /**
62
74
  * Creates a new list with all elements in reverse order.
63
75
  *
@@ -66,7 +78,7 @@ export let length = list => {
66
78
  *
67
79
  * @since v0.1.0
68
80
  */
69
- export let reverse = list => {
81
+ provide let reverse = list => {
70
82
  let rec iter = (list, acc) => {
71
83
  match (list) {
72
84
  [] => acc,
@@ -86,7 +98,7 @@ export let reverse = list => {
86
98
  *
87
99
  * @since v0.1.0
88
100
  */
89
- export let rec append = (list1, list2) => {
101
+ provide let rec append = (list1, list2) => {
90
102
  match (list1) {
91
103
  [] => list2,
92
104
  [first, ...rest] => [first, ...append(rest, list2)],
@@ -103,7 +115,7 @@ export let rec append = (list1, list2) => {
103
115
  *
104
116
  * @since v0.1.0
105
117
  */
106
- export let rec contains = (search, list) => {
118
+ provide let rec contains = (search, list) => {
107
119
  match (list) {
108
120
  [] => false,
109
121
  [first, ...rest] => first == search || contains(search, rest),
@@ -130,7 +142,7 @@ export let rec contains = (search, list) => {
130
142
  * @history v0.1.0: Originally named `foldLeft`
131
143
  * @history v0.2.0: Renamed to `reduce`
132
144
  */
133
- export let rec reduce = (fn, initial, list) => {
145
+ provide let rec reduce = (fn, initial, list) => {
134
146
  match (list) {
135
147
  [] => initial,
136
148
  [first, ...rest] => reduce(fn, fn(initial, first), rest),
@@ -157,7 +169,7 @@ export let rec reduce = (fn, initial, list) => {
157
169
  * @history v0.1.0: Originally named `foldRight`
158
170
  * @history v0.2.0: Renamed to `reduceRight`
159
171
  */
160
- export let rec reduceRight = (fn, initial, list) => {
172
+ provide let rec reduceRight = (fn, initial, list) => {
161
173
  match (list) {
162
174
  [] => initial,
163
175
  [first, ...rest] => fn(first, reduceRight(fn, initial, rest)),
@@ -174,7 +186,7 @@ export let rec reduceRight = (fn, initial, list) => {
174
186
  *
175
187
  * @since v0.1.0
176
188
  */
177
- export let rec map = (fn, list) => {
189
+ provide let rec map = (fn, list) => {
178
190
  match (list) {
179
191
  [] => [],
180
192
  [first, ...rest] => [fn(first), ...map(fn, rest)],
@@ -191,7 +203,7 @@ export let rec map = (fn, list) => {
191
203
  *
192
204
  * @since v0.1.0
193
205
  */
194
- export let mapi = (fn, list) => {
206
+ provide let mapi = (fn, list) => {
195
207
  let rec iter = (fn, list, index) => {
196
208
  match (list) {
197
209
  [] => [],
@@ -213,7 +225,7 @@ export let mapi = (fn, list) => {
213
225
  *
214
226
  * @since v0.2.0
215
227
  */
216
- export let rec flatMap = (fn, list) => {
228
+ provide let rec flatMap = (fn, list) => {
217
229
  match (list) {
218
230
  [] => [],
219
231
  [first, ...rest] => append(fn(first), flatMap(fn, rest)),
@@ -230,7 +242,7 @@ export let rec flatMap = (fn, list) => {
230
242
  *
231
243
  * @since v0.1.0
232
244
  */
233
- export let rec every = (fn, list) => {
245
+ provide let rec every = (fn, list) => {
234
246
  match (list) {
235
247
  [] => true,
236
248
  // The short-circuiting of `&&` makes this tail-recursive
@@ -248,7 +260,7 @@ export let rec every = (fn, list) => {
248
260
  *
249
261
  * @since v0.1.0
250
262
  */
251
- export let rec some = (fn, list) => {
263
+ provide let rec some = (fn, list) => {
252
264
  match (list) {
253
265
  [] => false,
254
266
  // The short-circuiting of `||` makes this tail-recursive
@@ -264,7 +276,7 @@ export let rec some = (fn, list) => {
264
276
  *
265
277
  * @since v0.1.0
266
278
  */
267
- export let rec forEach = (fn, list) => {
279
+ provide let rec forEach = (fn, list) => {
268
280
  match (list) {
269
281
  [] => void,
270
282
  [first, ...rest] => {
@@ -283,7 +295,7 @@ export let rec forEach = (fn, list) => {
283
295
  *
284
296
  * @since v0.1.0
285
297
  */
286
- export let forEachi = (fn, list) => {
298
+ provide let forEachi = (fn, list) => {
287
299
  let rec iter = (fn, list, index) => {
288
300
  match (list) {
289
301
  [] => void,
@@ -307,7 +319,7 @@ export let forEachi = (fn, list) => {
307
319
  *
308
320
  * @since v0.1.0
309
321
  */
310
- export let rec filter = (fn, list) => {
322
+ provide let rec filter = (fn, list) => {
311
323
  match (list) {
312
324
  [] => [],
313
325
  [first, ...rest] =>
@@ -326,13 +338,15 @@ export let rec filter = (fn, list) => {
326
338
  *
327
339
  * @since v0.3.0
328
340
  */
329
- export let filteri = (fn, list) => {
341
+ provide let filteri = (fn, list) => {
330
342
  let rec iter = (fn, list, index) => {
331
343
  match (list) {
332
344
  [] => [],
333
345
  [first, ...rest] =>
334
- if (fn(first, index)) [first, ...iter(fn, rest, index + 1)]
335
- else iter(fn, rest, index + 1),
346
+ if (fn(first, index))
347
+ [first, ...iter(fn, rest, index + 1)]
348
+ else
349
+ iter(fn, rest, index + 1),
336
350
  }
337
351
  }
338
352
  iter(fn, list, 0)
@@ -349,7 +363,7 @@ export let filteri = (fn, list) => {
349
363
  *
350
364
  * @since v0.1.0
351
365
  */
352
- export let rec reject = (fn, list) => {
366
+ provide let rec reject = (fn, list) => {
353
367
  match (list) {
354
368
  [] => [],
355
369
  [first, ...rest] =>
@@ -369,7 +383,7 @@ export let rec reject = (fn, list) => {
369
383
  * @history v0.2.0: Renamed to `head`
370
384
  * @history v0.3.0: Return type converted to `Option` type
371
385
  */
372
- export let head = list => {
386
+ provide let head = list => {
373
387
  match (list) {
374
388
  [] => None,
375
389
  [first, ..._] => Some(first),
@@ -388,7 +402,7 @@ export let head = list => {
388
402
  * @history v0.2.0: Renamed to `tail`
389
403
  * @history v0.3.0: Return type converted to `Option` type
390
404
  */
391
- export let tail = list => {
405
+ provide let tail = list => {
392
406
  match (list) {
393
407
  [] => None,
394
408
  [_, ...rest] => Some(rest),
@@ -407,7 +421,7 @@ export let tail = list => {
407
421
  * @history v0.1.0: Originally failed for index out-of-bounds or list empty
408
422
  * @history v0.3.0: Return type converted to `Option` type
409
423
  */
410
- export let rec nth = (index, list) => {
424
+ provide let rec nth = (index, list) => {
411
425
  if (index < 0) {
412
426
  None
413
427
  } else {
@@ -428,7 +442,7 @@ export let rec nth = (index, list) => {
428
442
  *
429
443
  * @since v0.1.0
430
444
  */
431
- export let rec flatten = list => {
445
+ provide let rec flatten = list => {
432
446
  match (list) {
433
447
  [] => [],
434
448
  [first, ...rest] => append(first, flatten(rest)),
@@ -438,8 +452,8 @@ export let rec flatten = list => {
438
452
  /**
439
453
  * Inserts a new value into a list at the specified index.
440
454
  *
441
- * @param value: The value to insert
442
455
  * @param index: The index to update
456
+ * @param value: The value to insert
443
457
  * @param list: The list to update
444
458
  * @returns The new list
445
459
  *
@@ -447,16 +461,19 @@ export let rec flatten = list => {
447
461
  * @throws Failure(String): When `index` is more than 0 and greater than the list size
448
462
  *
449
463
  * @since v0.1.0
464
+ * @history v0.6.0: Swapped order of `index` and `value` parameters
450
465
  */
451
- export let rec insert = (value, index, list) => {
466
+ provide let rec insert = (index, value, list) => {
452
467
  if (index < 0) {
453
468
  fail "insert index cannot be a negative number"
454
469
  } else {
455
470
  match (list) {
456
471
  [] => if (index == 0) [value] else fail "insert index is out-of-bounds",
457
472
  [first, ...rest] =>
458
- if (index == 0) [value, ...list]
459
- else [first, ...insert(value, index - 1, rest)],
473
+ if (index == 0)
474
+ [value, ...list]
475
+ else
476
+ [first, ...insert(index - 1, value, rest)],
460
477
  }
461
478
  }
462
479
  }
@@ -471,7 +488,7 @@ export let rec insert = (value, index, list) => {
471
488
  * @since v0.1.0
472
489
  * @history v0.2.0: Made the function tail-recursive
473
490
  */
474
- export let count = (fn, list) => {
491
+ provide let count = (fn, list) => {
475
492
  let rec iter = (n, list) => {
476
493
  match (list) {
477
494
  [] => n,
@@ -493,7 +510,7 @@ export let count = (fn, list) => {
493
510
  *
494
511
  * @since v0.1.0
495
512
  */
496
- export let part = (count, list) => {
513
+ provide let part = (count, list) => {
497
514
  if (count < 0) {
498
515
  fail "part count cannot be a negative number"
499
516
  } else {
@@ -502,8 +519,10 @@ export let part = (count, list) => {
502
519
  [] =>
503
520
  if (count > 0) fail "part count is out-of-bounds" else (list1, list2),
504
521
  [first, ...rest] =>
505
- if (count > 0) iter([first, ...list1], rest, count - 1)
506
- else (list1, list2),
522
+ if (count > 0)
523
+ iter([first, ...list1], rest, count - 1)
524
+ else
525
+ (list1, list2),
507
526
  }
508
527
  }
509
528
  let (pt1, pt2) = iter([], list, count)
@@ -512,24 +531,50 @@ export let part = (count, list) => {
512
531
  }
513
532
 
514
533
  /**
515
- * Rotates list elements by the specified amount to the left.
534
+ * Rotates list elements by the specified amount to the left, such that `n`th
535
+ * element is the first in the new list.
516
536
  *
517
537
  * If value is negative, list elements will be rotated by the
518
538
  * specified amount to the right. See examples.
519
539
  *
520
- * @param count: The number of elements to rotate by
540
+ * @param n: The number of elements to rotate by
521
541
  * @param list: The list to be rotated
522
542
  *
523
543
  * @example List.rotate(2, [1, 2, 3, 4, 5]) // [3, 4, 5, 1, 2]
524
544
  * @example List.rotate(-1, [1, 2, 3, 4, 5]) // [5, 1, 2, 3, 4]
525
- *
526
- * @throws Failure(String): When the list doesn't contain at least the required amount of elements
545
+ * @example List.rotate(-7, [1, 2, 3, 4, 5]) // [4, 5, 1, 2, 3]
527
546
  *
528
547
  * @since v0.1.0
548
+ *
549
+ * @history v0.6.0: No longer throws if `count` outside list length bounds
529
550
  */
530
- export let rotate = (count, list) => {
531
- let (beginning, end) =
532
- if (count >= 0) part(count, list) else part(length(list) + count, list)
551
+ provide let rotate = (n, list) => {
552
+ // Optimization: only compute the list length (O(n)) if n is negative
553
+ // or if the entire list is exhausted when partitioning. This should improve
554
+ // performance if the list is very long but n is small
555
+ let getSplitI = () => {
556
+ let len = length(list)
557
+ if (len == 0) 0 else n % len
558
+ }
559
+ let (beginning, end) = if (n >= 0) {
560
+ let rec iter = (list1, list2, n) => {
561
+ match (list2) {
562
+ [] => if (n > 0) None else Some((list1, list2)),
563
+ [first, ...rest] =>
564
+ if (n > 0)
565
+ iter([first, ...list1], rest, n - 1)
566
+ else
567
+ Some((list1, list2)),
568
+ }
569
+ }
570
+ let res = iter([], list, n)
571
+ match (res) {
572
+ None => part(getSplitI(), list),
573
+ Some((pt1, pt2)) => (reverse(pt1), pt2),
574
+ }
575
+ } else {
576
+ part(getSplitI(), list)
577
+ }
533
578
  append(end, beginning)
534
579
  }
535
580
 
@@ -544,13 +589,15 @@ export let rotate = (count, list) => {
544
589
  * @history v0.1.0: Originally named `uniq`
545
590
  * @history v0.2.0: Renamed to `unique`
546
591
  */
547
- export let unique = list => {
592
+ provide let unique = list => {
548
593
  let rec iter = (list, acc) => {
549
594
  match (list) {
550
595
  [] => reverse(acc),
551
596
  [first, ...rest] =>
552
- if (contains(first, acc)) iter(rest, acc)
553
- else iter(rest, [first, ...acc]),
597
+ if (contains(first, acc))
598
+ iter(rest, acc)
599
+ else
600
+ iter(rest, [first, ...acc]),
554
601
  }
555
602
  }
556
603
  iter(list, [])
@@ -573,7 +620,7 @@ export let unique = list => {
573
620
  *
574
621
  * @since v0.5.3
575
622
  */
576
- export let zip = (list1, list2) => {
623
+ provide let zip = (list1, list2) => {
577
624
  let rec zipInner = (list1, list2, acc) => {
578
625
  match ((list1, list2)) {
579
626
  ([first1, ...rest1], [first2, ...rest2]) =>
@@ -604,7 +651,7 @@ export let zip = (list1, list2) => {
604
651
  *
605
652
  * @since v0.5.3
606
653
  */
607
- export let zipWith = (fn, list1, list2) => {
654
+ provide let zipWith = (fn, list1, list2) => {
608
655
  let rec zipWithInner = (list1, list2, acc) => {
609
656
  match ((list1, list2)) {
610
657
  ([first1, ...rest1], [first2, ...rest2]) =>
@@ -623,10 +670,14 @@ export let zipWith = (fn, list1, list2) => {
623
670
  *
624
671
  * @since v0.5.3
625
672
  */
626
- export let unzip = list => {
627
- reduceRight(((first, second), (firstUnzipped, secondUnzipped)) => {
628
- ([first, ...firstUnzipped], [second, ...secondUnzipped])
629
- }, ([], []), list)
673
+ provide let unzip = list => {
674
+ reduceRight(
675
+ ((first, second), (firstUnzipped, secondUnzipped)) => {
676
+ ([first, ...firstUnzipped], [second, ...secondUnzipped])
677
+ },
678
+ ([], []),
679
+ list
680
+ )
630
681
  }
631
682
 
632
683
  /**
@@ -641,13 +692,13 @@ export let unzip = list => {
641
692
  *
642
693
  * @since v0.2.0
643
694
  */
644
- export let rec drop = (count, list) => {
695
+ provide let rec drop = (count, list) => {
645
696
  if (count < 0) {
646
697
  fail "number of items to drop cannot be a negative number"
647
698
  } else {
648
699
  match ((count, list)) {
649
700
  (_, []) => [],
650
- (n, _) when n == 0 => list,
701
+ (0, _) => list,
651
702
  (n, [first, ...rest]) => drop(n - 1, rest),
652
703
  }
653
704
  }
@@ -664,7 +715,7 @@ export let rec drop = (count, list) => {
664
715
  *
665
716
  * @since v0.2.0
666
717
  */
667
- export let rec dropWhile = (fn, list) => {
718
+ provide let rec dropWhile = (fn, list) => {
668
719
  match (list) {
669
720
  [] => list,
670
721
  [first, ...rest] => if (fn(first)) dropWhile(fn, rest) else list,
@@ -683,13 +734,13 @@ export let rec dropWhile = (fn, list) => {
683
734
  *
684
735
  * @since v0.2.0
685
736
  */
686
- export let rec take = (count, list) => {
737
+ provide let rec take = (count, list) => {
687
738
  if (count < 0) {
688
739
  fail "number of items to take cannot be a negative number"
689
740
  } else {
690
741
  match ((count, list)) {
691
742
  (_, []) => list,
692
- (n, _) when n == 0 => [],
743
+ (0, _) => [],
693
744
  (n, [first, ...rest]) => [first, ...take(n - 1, rest)],
694
745
  }
695
746
  }
@@ -706,7 +757,7 @@ export let rec take = (count, list) => {
706
757
  *
707
758
  * @since v0.2.0
708
759
  */
709
- export let rec takeWhile = (fn, list) => {
760
+ provide let rec takeWhile = (fn, list) => {
710
761
  match (list) {
711
762
  [] => [],
712
763
  [first, ...rest] => if (fn(first)) [first, ...takeWhile(fn, rest)] else [],
@@ -724,7 +775,7 @@ export let rec takeWhile = (fn, list) => {
724
775
  * @history v0.2.0: Originally failed if the list was empty
725
776
  * @history v0.3.0: Return type converted to `Option` type
726
777
  */
727
- export let rec find = (fn, list) => {
778
+ provide let rec find = (fn, list) => {
728
779
  match (list) {
729
780
  [] => None,
730
781
  [first, ...rest] => if (fn(first)) Some(first) else find(fn, rest),
@@ -742,7 +793,7 @@ export let rec find = (fn, list) => {
742
793
  * @history v0.2.0: Originally failed if the list was empty
743
794
  * @history v0.3.0: Return type converted to `Option` type
744
795
  */
745
- export let findIndex = (fn, list) => {
796
+ provide let findIndex = (fn, list) => {
746
797
  let rec findItemIndex = (l, index) => {
747
798
  match (l) {
748
799
  [] => None,
@@ -763,7 +814,7 @@ export let findIndex = (fn, list) => {
763
814
  *
764
815
  * @since v0.2.0
765
816
  */
766
- export let product = (list1, list2) => {
817
+ provide let product = (list1, list2) => {
767
818
  let mut list = []
768
819
  forEach(aItem => {
769
820
  forEach(bItem => {
@@ -787,7 +838,7 @@ export let product = (list1, list2) => {
787
838
  *
788
839
  * @since v0.2.0
789
840
  */
790
- export let sub = (start, length, list) => {
841
+ provide let sub = (start, length, list) => {
791
842
  take(length, drop(start, list))
792
843
  }
793
844
 
@@ -801,7 +852,7 @@ export let sub = (start, length, list) => {
801
852
  *
802
853
  * @since v0.4.0
803
854
  */
804
- export let join = (separator: String, list: List<String>) => {
855
+ provide let join = (separator: String, list: List<String>) => {
805
856
  let rec iter = (sep, acc, rem) => {
806
857
  match (rem) {
807
858
  [] => acc,
@@ -831,7 +882,7 @@ export let join = (separator: String, list: List<String>) => {
831
882
  *
832
883
  * @since v0.4.5
833
884
  */
834
- export let rec revAppend = (list1, list2) => {
885
+ provide let rec revAppend = (list1, list2) => {
835
886
  match (list1) {
836
887
  [hd, ...tl] => revAppend(tl, [hd, ...list2]),
837
888
  [] => list2,
@@ -842,13 +893,14 @@ export let rec revAppend = (list1, list2) => {
842
893
  * Sorts the given list based on a given comparator function. The resulting list is sorted in increasing order.
843
894
  *
844
895
  * 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.
845
- * @param comp: The comparator function used to indicate sort order
896
+ * @param compare: The comparator function used to indicate sort order
846
897
  * @param list: The list to be sorted
847
898
  * @returns The sorted list
848
899
  *
849
900
  * @since v0.4.5
901
+ * @history v0.6.0: Made `compare` a default argument
850
902
  */
851
- export let sort = (comp, list) => {
903
+ provide let sort = (compare=compare, list) => {
852
904
  let rec merge = (left, right, list) => {
853
905
  match ((left, right)) {
854
906
  (_, []) => {
@@ -858,7 +910,7 @@ export let sort = (comp, list) => {
858
910
  revAppend(list, right)
859
911
  },
860
912
  ([lhd, ...ltl], [rhd, ...rtl]) => {
861
- if (comp(lhd, rhd) < 0) {
913
+ if (compare(lhd, rhd) < 0) {
862
914
  merge(ltl, right, append([lhd], list))
863
915
  } else {
864
916
  merge(left, rtl, append([rhd], list))