@grain/stdlib 0.6.5 → 0.7.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 (139) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +1 -1
  3. package/README.md +2 -2
  4. package/array.gr +55 -7
  5. package/array.md +123 -77
  6. package/bigint.md +30 -30
  7. package/buffer.gr +20 -53
  8. package/buffer.md +47 -47
  9. package/bytes.gr +111 -35
  10. package/bytes.md +111 -32
  11. package/char.gr +201 -99
  12. package/char.md +361 -34
  13. package/exception.gr +11 -11
  14. package/exception.md +26 -1
  15. package/float32.gr +327 -3
  16. package/float32.md +606 -19
  17. package/float64.gr +320 -3
  18. package/float64.md +606 -19
  19. package/fs.gr +1082 -0
  20. package/fs.md +630 -0
  21. package/hash.gr +142 -88
  22. package/hash.md +102 -14
  23. package/int16.md +23 -23
  24. package/int32.gr +25 -4
  25. package/int32.md +65 -30
  26. package/int64.gr +26 -1
  27. package/int64.md +65 -30
  28. package/int8.md +23 -23
  29. package/json.gr +366 -51
  30. package/json.md +418 -2
  31. package/list.gr +387 -49
  32. package/list.md +492 -69
  33. package/map.gr +20 -12
  34. package/map.md +44 -38
  35. package/marshal.gr +41 -40
  36. package/marshal.md +2 -2
  37. package/number.gr +159 -30
  38. package/number.md +215 -38
  39. package/option.md +21 -21
  40. package/package.json +5 -3
  41. package/path.gr +48 -0
  42. package/path.md +103 -12
  43. package/pervasives.gr +2 -2
  44. package/pervasives.md +37 -37
  45. package/priorityqueue.gr +7 -7
  46. package/priorityqueue.md +19 -19
  47. package/queue.gr +183 -29
  48. package/queue.md +296 -40
  49. package/random.md +6 -6
  50. package/range.gr +4 -4
  51. package/range.md +6 -6
  52. package/rational.md +16 -16
  53. package/regex.gr +52 -51
  54. package/regex.md +11 -11
  55. package/result.md +16 -16
  56. package/runtime/atof/common.md +39 -39
  57. package/runtime/atof/decimal.gr +6 -6
  58. package/runtime/atof/decimal.md +8 -8
  59. package/runtime/atof/lemire.gr +5 -5
  60. package/runtime/atof/lemire.md +1 -1
  61. package/runtime/atof/parse.gr +16 -16
  62. package/runtime/atof/parse.md +2 -2
  63. package/runtime/atof/slow.md +1 -1
  64. package/runtime/atof/table.md +2 -2
  65. package/runtime/atoi/parse.gr +3 -3
  66. package/runtime/atoi/parse.md +1 -1
  67. package/runtime/bigint.gr +15 -47
  68. package/runtime/bigint.md +54 -60
  69. package/runtime/compare.gr +2 -2
  70. package/runtime/compare.md +1 -1
  71. package/runtime/dataStructures.md +33 -33
  72. package/runtime/debugPrint.gr +4 -1
  73. package/runtime/debugPrint.md +9 -9
  74. package/runtime/equal.gr +99 -77
  75. package/runtime/equal.md +1 -1
  76. package/runtime/exception.gr +62 -82
  77. package/runtime/exception.md +62 -11
  78. package/runtime/gc.gr +39 -45
  79. package/runtime/gc.md +4 -4
  80. package/runtime/malloc.gr +7 -7
  81. package/runtime/malloc.md +4 -4
  82. package/runtime/math/kernel/cos.gr +70 -0
  83. package/runtime/math/kernel/cos.md +14 -0
  84. package/runtime/math/kernel/sin.gr +65 -0
  85. package/runtime/math/kernel/sin.md +14 -0
  86. package/runtime/math/kernel/tan.gr +136 -0
  87. package/runtime/math/kernel/tan.md +14 -0
  88. package/runtime/math/rempio2.gr +244 -0
  89. package/runtime/math/rempio2.md +14 -0
  90. package/runtime/math/trig.gr +130 -0
  91. package/runtime/math/trig.md +28 -0
  92. package/runtime/math/umuldi.gr +26 -0
  93. package/runtime/math/umuldi.md +14 -0
  94. package/runtime/numberUtils.gr +29 -29
  95. package/runtime/numberUtils.md +12 -12
  96. package/runtime/numbers.gr +373 -381
  97. package/runtime/numbers.md +79 -73
  98. package/runtime/string.gr +37 -105
  99. package/runtime/string.md +3 -9
  100. package/runtime/unsafe/constants.md +24 -24
  101. package/runtime/unsafe/conv.md +13 -13
  102. package/runtime/unsafe/memory.gr +24 -20
  103. package/runtime/unsafe/memory.md +27 -7
  104. package/runtime/unsafe/offsets.gr +36 -0
  105. package/runtime/unsafe/offsets.md +88 -0
  106. package/runtime/unsafe/panic.gr +28 -0
  107. package/runtime/unsafe/panic.md +14 -0
  108. package/runtime/unsafe/tags.md +32 -32
  109. package/runtime/unsafe/wasmf32.md +28 -28
  110. package/runtime/unsafe/wasmf64.md +28 -28
  111. package/runtime/unsafe/wasmi32.md +47 -47
  112. package/runtime/unsafe/wasmi64.md +50 -50
  113. package/runtime/utf8.gr +189 -0
  114. package/runtime/utf8.md +117 -0
  115. package/runtime/wasi.gr +4 -2
  116. package/runtime/wasi.md +138 -138
  117. package/set.gr +18 -11
  118. package/set.md +42 -36
  119. package/stack.gr +171 -2
  120. package/stack.md +297 -15
  121. package/string.gr +352 -557
  122. package/string.md +77 -34
  123. package/uint16.gr +81 -0
  124. package/uint16.md +183 -22
  125. package/uint32.gr +25 -4
  126. package/uint32.md +63 -28
  127. package/uint64.gr +25 -5
  128. package/uint64.md +63 -28
  129. package/uint8.gr +81 -0
  130. package/uint8.md +183 -22
  131. package/uri.gr +57 -53
  132. package/uri.md +11 -12
  133. package/wasi/file.gr +67 -59
  134. package/wasi/file.md +39 -39
  135. package/wasi/process.md +5 -5
  136. package/wasi/random.md +3 -3
  137. package/wasi/time.md +4 -4
  138. package/runtime/utils/printing.gr +0 -60
  139. package/runtime/utils/printing.md +0 -26
package/set.gr CHANGED
@@ -11,7 +11,6 @@ module Set
11
11
  from "list" include List
12
12
  from "array" include Array
13
13
  from "hash" include Hash
14
- use Hash.{ hash }
15
14
 
16
15
  record rec Bucket<t> {
17
16
  mut key: t,
@@ -20,6 +19,7 @@ record rec Bucket<t> {
20
19
 
21
20
  abstract record Set<k> {
22
21
  mut size: Number,
22
+ hashInstance: Hash.HashInstance,
23
23
  mut buckets: Array<Option<Bucket<k>>>,
24
24
  }
25
25
 
@@ -41,25 +41,28 @@ provide record InternalSetStats {
41
41
  * @param size: The initial storage size of the set
42
42
  * @returns An empty set with the given initial storage size
43
43
  *
44
+ * @throws Failure(String): If WASI random_get fails
45
+ *
44
46
  * @since v0.3.0
45
47
  * @history v0.6.0: Merged with `makeSized`; modified signature to accept size
46
48
  */
47
49
  provide let make = (size=16) => {
48
50
  let buckets = Array.make(size, None)
49
- { size: 0, buckets }
51
+ let hashInstance = Hash.make()
52
+ { size: 0, hashInstance, buckets }
50
53
  }
51
54
 
52
- let getBucketIndex = (key, buckets) => {
55
+ let getBucketIndex = (hashInstance, key, buckets) => {
53
56
  let bucketsLength = Array.length(buckets)
54
- let hashedKey = hash(key)
57
+ let hashedKey = Hash.hash(hashInstance, key)
55
58
  hashedKey % bucketsLength
56
59
  }
57
60
 
58
- let rec copyNodeWithNewHash = (oldNode, next, tail) => {
61
+ let rec copyNodeWithNewHash = (hashInstance, oldNode, next, tail) => {
59
62
  match (oldNode) {
60
63
  None => void,
61
64
  Some(node) => {
62
- let idx = getBucketIndex(node.key, next)
65
+ let idx = getBucketIndex(hashInstance, node.key, next)
63
66
  let newNode = Some(node)
64
67
  match (tail[idx]) {
65
68
  None => {
@@ -73,7 +76,7 @@ let rec copyNodeWithNewHash = (oldNode, next, tail) => {
73
76
  // Always place this node as the new tail
74
77
  tail[idx] = newNode
75
78
  // Recurse with the next node
76
- copyNodeWithNewHash(node.next, next, tail)
79
+ copyNodeWithNewHash(hashInstance, node.next, next, tail)
77
80
  },
78
81
  }
79
82
  }
@@ -87,8 +90,9 @@ let resize = set => {
87
90
  // This tracks the tail nodes so we can set their `next` to None
88
91
  let tailNodes = Array.make(nextSize, None)
89
92
  set.buckets = nextBuckets
93
+ let hashInstance = set.hashInstance
90
94
  Array.forEach(old => {
91
- copyNodeWithNewHash(old, nextBuckets, tailNodes)
95
+ copyNodeWithNewHash(hashInstance, old, nextBuckets, tailNodes)
92
96
  }, currentBuckets)
93
97
  Array.forEach(tail => {
94
98
  match (tail) {
@@ -124,7 +128,8 @@ let rec nodeInBucket = (key, node) => {
124
128
  */
125
129
  provide let add = (key, set) => {
126
130
  let buckets = set.buckets
127
- let idx = getBucketIndex(key, buckets)
131
+ let hashInstance = set.hashInstance
132
+ let idx = getBucketIndex(hashInstance, key, buckets)
128
133
  let bucket = buckets[idx]
129
134
  match (bucket) {
130
135
  None => {
@@ -157,7 +162,8 @@ provide let add = (key, set) => {
157
162
  */
158
163
  provide let contains = (key, set) => {
159
164
  let buckets = set.buckets
160
- let idx = getBucketIndex(key, buckets)
165
+ let hashInstance = set.hashInstance
166
+ let idx = getBucketIndex(hashInstance, key, buckets)
161
167
  let bucket = buckets[idx]
162
168
  match (bucket) {
163
169
  None => false,
@@ -189,7 +195,8 @@ let rec removeInBucket = (key, node) => {
189
195
  */
190
196
  provide let remove = (key, set) => {
191
197
  let buckets = set.buckets
192
- let idx = getBucketIndex(key, buckets)
198
+ let hashInstance = set.hashInstance
199
+ let idx = getBucketIndex(hashInstance, key, buckets)
193
200
  let bucket = buckets[idx]
194
201
  match (bucket) {
195
202
  None => void,
package/set.md CHANGED
@@ -55,7 +55,7 @@ Functions and constants included in the Set module.
55
55
  </details>
56
56
 
57
57
  ```grain
58
- make : (?size: Number) => Set<a>
58
+ make: (?size: Number) => Set<a>
59
59
  ```
60
60
 
61
61
  Creates a new empty set with an initial storage of the given size. As
@@ -75,6 +75,12 @@ Returns:
75
75
  |----|-----------|
76
76
  |`Set<a>`|An empty set with the given initial storage size|
77
77
 
78
+ Throws:
79
+
80
+ `Failure(String)`
81
+
82
+ * If WASI random_get fails
83
+
78
84
  ### Set.**add**
79
85
 
80
86
  <details disabled>
@@ -83,7 +89,7 @@ No other changes yet.
83
89
  </details>
84
90
 
85
91
  ```grain
86
- add : (key: a, set: Set<a>) => Void
92
+ add: (key: a, set: Set<a>) => Void
87
93
  ```
88
94
 
89
95
  Adds a new value to the set. If the value already exists, nothing happens.
@@ -103,7 +109,7 @@ No other changes yet.
103
109
  </details>
104
110
 
105
111
  ```grain
106
- contains : (key: a, set: Set<a>) => Bool
112
+ contains: (key: a, set: Set<a>) => Bool
107
113
  ```
108
114
 
109
115
  Determines if the set contains the given value.
@@ -129,7 +135,7 @@ No other changes yet.
129
135
  </details>
130
136
 
131
137
  ```grain
132
- remove : (key: a, set: Set<a>) => Void
138
+ remove: (key: a, set: Set<a>) => Void
133
139
  ```
134
140
 
135
141
  Removes the given value from the set. If the value doesn't exist, nothing happens.
@@ -149,7 +155,7 @@ No other changes yet.
149
155
  </details>
150
156
 
151
157
  ```grain
152
- size : (set: Set<a>) => Number
158
+ size: (set: Set<a>) => Number
153
159
  ```
154
160
 
155
161
  Provides the count of values within the set.
@@ -174,7 +180,7 @@ No other changes yet.
174
180
  </details>
175
181
 
176
182
  ```grain
177
- isEmpty : (set: Set<a>) => Bool
183
+ isEmpty: (set: Set<a>) => Bool
178
184
  ```
179
185
 
180
186
  Determines if the set contains no elements.
@@ -199,7 +205,7 @@ No other changes yet.
199
205
  </details>
200
206
 
201
207
  ```grain
202
- clear : (set: Set<a>) => Void
208
+ clear: (set: Set<a>) => Void
203
209
  ```
204
210
 
205
211
  Resets the set by removing all values.
@@ -225,7 +231,7 @@ Parameters:
225
231
  </details>
226
232
 
227
233
  ```grain
228
- forEach : (fn: (a => Void), set: Set<a>) => Void
234
+ forEach: (fn: (a => Void), set: Set<a>) => Void
229
235
  ```
230
236
 
231
237
  Iterates the set, calling an iterator function on each element.
@@ -245,7 +251,7 @@ No other changes yet.
245
251
  </details>
246
252
 
247
253
  ```grain
248
- reduce : (fn: ((a, b) => a), init: a, set: Set<b>) => a
254
+ reduce: (fn: ((a, b) => a), init: a, set: Set<b>) => a
249
255
  ```
250
256
 
251
257
  Combines all elements of a set using a reducer function.
@@ -272,7 +278,7 @@ No other changes yet.
272
278
  </details>
273
279
 
274
280
  ```grain
275
- filter : (fn: (a => Bool), set: Set<a>) => Void
281
+ filter: (fn: (a => Bool), set: Set<a>) => Void
276
282
  ```
277
283
 
278
284
  Removes elements from a set where a predicate function returns `false`.
@@ -292,7 +298,7 @@ No other changes yet.
292
298
  </details>
293
299
 
294
300
  ```grain
295
- reject : (fn: (a => Bool), set: Set<a>) => Void
301
+ reject: (fn: (a => Bool), set: Set<a>) => Void
296
302
  ```
297
303
 
298
304
  Removes elements from a set where a predicate function returns `true`.
@@ -312,7 +318,7 @@ No other changes yet.
312
318
  </details>
313
319
 
314
320
  ```grain
315
- toList : (set: Set<a>) => List<a>
321
+ toList: (set: Set<a>) => List<a>
316
322
  ```
317
323
 
318
324
  Converts a set into a list of its elements.
@@ -337,7 +343,7 @@ No other changes yet.
337
343
  </details>
338
344
 
339
345
  ```grain
340
- fromList : (list: List<a>) => Set<a>
346
+ fromList: (list: List<a>) => Set<a>
341
347
  ```
342
348
 
343
349
  Creates a set from a list.
@@ -362,7 +368,7 @@ No other changes yet.
362
368
  </details>
363
369
 
364
370
  ```grain
365
- toArray : (set: Set<a>) => Array<a>
371
+ toArray: (set: Set<a>) => Array<a>
366
372
  ```
367
373
 
368
374
  Converts a set into an array of its elements.
@@ -387,7 +393,7 @@ No other changes yet.
387
393
  </details>
388
394
 
389
395
  ```grain
390
- fromArray : (array: Array<a>) => Set<a>
396
+ fromArray: (array: Array<a>) => Set<a>
391
397
  ```
392
398
 
393
399
  Creates a set from an array.
@@ -412,7 +418,7 @@ No other changes yet.
412
418
  </details>
413
419
 
414
420
  ```grain
415
- union : (set1: Set<a>, set2: Set<a>) => Set<a>
421
+ union: (set1: Set<a>, set2: Set<a>) => Set<a>
416
422
  ```
417
423
 
418
424
  Combines two sets into a single set containing all elements from both sets.
@@ -438,7 +444,7 @@ No other changes yet.
438
444
  </details>
439
445
 
440
446
  ```grain
441
- diff : (set1: Set<a>, set2: Set<a>) => Set<a>
447
+ diff: (set1: Set<a>, set2: Set<a>) => Set<a>
442
448
  ```
443
449
 
444
450
  Combines two sets into a single set containing only the elements not shared between both sets.
@@ -464,7 +470,7 @@ No other changes yet.
464
470
  </details>
465
471
 
466
472
  ```grain
467
- intersect : (set1: Set<a>, set2: Set<a>) => Set<a>
473
+ intersect: (set1: Set<a>, set2: Set<a>) => Set<a>
468
474
  ```
469
475
 
470
476
  Combines two sets into a single set containing only the elements shared between both sets.
@@ -497,7 +503,7 @@ Returns:
497
503
  </details>
498
504
 
499
505
  ```grain
500
- getInternalStats : (set: Set<a>) => InternalSetStats
506
+ getInternalStats: (set: Set<a>) => InternalSetStats
501
507
  ```
502
508
 
503
509
  Provides data representing the internal state state of the set.
@@ -559,7 +565,7 @@ Functions and constants included in the Set.Immutable module.
559
565
  </details>
560
566
 
561
567
  ```grain
562
- empty : Set<a>
568
+ empty: Set<a>
563
569
  ```
564
570
 
565
571
  An empty set
@@ -579,7 +585,7 @@ An empty set
579
585
  </details>
580
586
 
581
587
  ```grain
582
- size : (set: Set<a>) => Number
588
+ size: (set: Set<a>) => Number
583
589
  ```
584
590
 
585
591
  Provides the count of values within the set.
@@ -611,7 +617,7 @@ Returns:
611
617
  </details>
612
618
 
613
619
  ```grain
614
- isEmpty : (set: Set<a>) => Bool
620
+ isEmpty: (set: Set<a>) => Bool
615
621
  ```
616
622
 
617
623
  Determines if the set contains no elements.
@@ -643,7 +649,7 @@ Returns:
643
649
  </details>
644
650
 
645
651
  ```grain
646
- add : (key: a, set: Set<a>) => Set<a>
652
+ add: (key: a, set: Set<a>) => Set<a>
647
653
  ```
648
654
 
649
655
  Produces a new set by inserting the given value into the set. If the value
@@ -677,7 +683,7 @@ Returns:
677
683
  </details>
678
684
 
679
685
  ```grain
680
- contains : (key: a, set: Set<a>) => Bool
686
+ contains: (key: a, set: Set<a>) => Bool
681
687
  ```
682
688
 
683
689
  Determines if the set contains the given value.
@@ -710,7 +716,7 @@ Returns:
710
716
  </details>
711
717
 
712
718
  ```grain
713
- remove : (key: a, set: Set<a>) => Set<a>
719
+ remove: (key: a, set: Set<a>) => Set<a>
714
720
  ```
715
721
 
716
722
  Produces a new set without the given element. If the value doesn't exist in
@@ -744,7 +750,7 @@ Returns:
744
750
  </details>
745
751
 
746
752
  ```grain
747
- forEach : (fn: (a => Void), set: Set<a>) => Void
753
+ forEach: (fn: (a => Void), set: Set<a>) => Void
748
754
  ```
749
755
 
750
756
  Iterates the set, calling an iterator function on each element.
@@ -771,7 +777,7 @@ Parameters:
771
777
  </details>
772
778
 
773
779
  ```grain
774
- reduce : (fn: ((a, b) => a), init: a, set: Set<b>) => a
780
+ reduce: (fn: ((a, b) => a), init: a, set: Set<b>) => a
775
781
  ```
776
782
 
777
783
  Combines all elements of a set using a reducer function.
@@ -805,7 +811,7 @@ Returns:
805
811
  </details>
806
812
 
807
813
  ```grain
808
- filter : (fn: (a => Bool), set: Set<a>) => Set<a>
814
+ filter: (fn: (a => Bool), set: Set<a>) => Set<a>
809
815
  ```
810
816
 
811
817
  Produces a new set without the elements from the input set where a predicate function returns `false`.
@@ -838,7 +844,7 @@ Returns:
838
844
  </details>
839
845
 
840
846
  ```grain
841
- reject : (fn: (a => Bool), set: Set<a>) => Set<a>
847
+ reject: (fn: (a => Bool), set: Set<a>) => Set<a>
842
848
  ```
843
849
 
844
850
  Produces a new set without the elements from the input set where a predicate function returns `true`.
@@ -871,7 +877,7 @@ Returns:
871
877
  </details>
872
878
 
873
879
  ```grain
874
- union : (set1: Set<a>, set2: Set<a>) => Set<a>
880
+ union: (set1: Set<a>, set2: Set<a>) => Set<a>
875
881
  ```
876
882
 
877
883
  Combines two sets into a single set containing all elements from both sets.
@@ -904,7 +910,7 @@ Returns:
904
910
  </details>
905
911
 
906
912
  ```grain
907
- diff : (set1: Set<a>, set2: Set<a>) => Set<a>
913
+ diff: (set1: Set<a>, set2: Set<a>) => Set<a>
908
914
  ```
909
915
 
910
916
  Combines two sets into a single set containing only the elements not shared between both sets.
@@ -937,7 +943,7 @@ Returns:
937
943
  </details>
938
944
 
939
945
  ```grain
940
- intersect : (set1: Set<a>, set2: Set<a>) => Set<a>
946
+ intersect: (set1: Set<a>, set2: Set<a>) => Set<a>
941
947
  ```
942
948
 
943
949
  Combines two sets into a single set containing only the elements shared between both sets.
@@ -970,7 +976,7 @@ Returns:
970
976
  </details>
971
977
 
972
978
  ```grain
973
- fromList : (list: List<a>) => Set<a>
979
+ fromList: (list: List<a>) => Set<a>
974
980
  ```
975
981
 
976
982
  Creates a set from a list.
@@ -1002,7 +1008,7 @@ Returns:
1002
1008
  </details>
1003
1009
 
1004
1010
  ```grain
1005
- toList : (set: Set<a>) => List<a>
1011
+ toList: (set: Set<a>) => List<a>
1006
1012
  ```
1007
1013
 
1008
1014
  Converts a set into a list of its elements.
@@ -1034,7 +1040,7 @@ Returns:
1034
1040
  </details>
1035
1041
 
1036
1042
  ```grain
1037
- fromArray : (array: Array<a>) => Set<a>
1043
+ fromArray: (array: Array<a>) => Set<a>
1038
1044
  ```
1039
1045
 
1040
1046
  Creates a set from an array.
@@ -1066,7 +1072,7 @@ Returns:
1066
1072
  </details>
1067
1073
 
1068
1074
  ```grain
1069
- toArray : (set: Set<a>) => Array<a>
1075
+ toArray: (set: Set<a>) => Array<a>
1070
1076
  ```
1071
1077
 
1072
1078
  Converts a set into an array of its elements.
package/stack.gr CHANGED
@@ -25,12 +25,12 @@ abstract record Stack<a> {
25
25
  /**
26
26
  * Creates a new stack with an initial storage of the given size. As values are
27
27
  * added or removed, the internal storage may grow or shrink. Generally, you
28
- * won’t need to care about the storage size of your map and can use the
28
+ * won’t need to care about the storage size of your stack and can use the
29
29
  * default size.
30
30
  *
31
31
  * @param size: The initial storage size of the stack
32
32
  * @returns An empty stack
33
- *
33
+ *
34
34
  * @since v0.6.0
35
35
  */
36
36
  provide let make = (size=16) => {
@@ -134,6 +134,95 @@ provide let copy = stack => {
134
134
  { size, array: Array.copy(array) }
135
135
  }
136
136
 
137
+ /**
138
+ * Creates a list containing the elements of a stack.
139
+ *
140
+ * @param stack: The stack to convert
141
+ * @returns A list containing all stack values
142
+ *
143
+ * @example
144
+ * let stack = Stack.make()
145
+ * Stack.push(1, stack)
146
+ * Stack.push(2, stack)
147
+ * assert Stack.toList(stack) == [2, 1]
148
+ *
149
+ * @since v0.7.0
150
+ */
151
+ provide let toList = stack => {
152
+ let size = stack.size
153
+ List.init(size, i => match (stack.array[size - i - 1]) {
154
+ Some(v) => v,
155
+ None => fail "Impossible: None in stack bounds on toList",
156
+ })
157
+ }
158
+
159
+ /**
160
+ * Creates a stack from a list.
161
+ *
162
+ * @param list: The list to convert
163
+ * @returns A stack containing all list values
164
+ *
165
+ * @example
166
+ * let stack = Stack.fromList([3, 2, 1])
167
+ * assert Stack.pop(stack) == Some(3)
168
+ * assert Stack.pop(stack) == Some(2)
169
+ * assert Stack.pop(stack) == Some(1)
170
+ * assert Stack.pop(stack) == None
171
+ *
172
+ * @since v0.7.0
173
+ */
174
+ provide let fromList = list => {
175
+ let stack = make(size=List.length(list))
176
+ List.forEach(v => push(v, stack), List.reverse(list))
177
+ stack
178
+ }
179
+
180
+ /**
181
+ * Creates an array containing the elements of a stack.
182
+ *
183
+ * @param stack: The stack to convert
184
+ * @returns An array containing all stack values
185
+ *
186
+ * @example
187
+ * let stack = Stack.make()
188
+ * Stack.push(1, stack)
189
+ * Stack.push(2, stack)
190
+ * assert Stack.toArray(stack) == [> 2, 1]
191
+ *
192
+ * @since v0.7.0
193
+ */
194
+ provide let toArray = stack => {
195
+ let size = stack.size
196
+ Array.init(size, i => match (stack.array[size - i - 1]) {
197
+ Some(v) => v,
198
+ None => fail "Impossible: None in stack bounds on toList",
199
+ })
200
+ }
201
+
202
+ /**
203
+ * Creates a stack from an array.
204
+ *
205
+ * @param arr: The array to convert
206
+ * @returns A stack containing all array values
207
+ *
208
+ * @example
209
+ * let s = Stack.fromArray([> 3, 2, 1])
210
+ * assert Stack.pop(s) == Some(3)
211
+ * assert Stack.pop(s) == Some(2)
212
+ * assert Stack.pop(s) == Some(1)
213
+ * assert Stack.pop(s) == None
214
+ *
215
+ * @since v0.7.0
216
+ */
217
+ provide let fromArray = arr => {
218
+ let arrLen = Array.length(arr)
219
+ let stack = make(size=arrLen)
220
+ for (let mut i = arrLen - 1; i >= 0; i -= 1) {
221
+ push(arr[i], stack)
222
+ }
223
+ stack
224
+ }
225
+
137
226
  /**
138
227
  * An immutable stack implementation.
139
228
  */
@@ -237,4 +326,84 @@ provide module Immutable {
237
326
  { data } => List.length(data),
238
327
  }
239
328
  }
329
+
330
+ /**
331
+ * Creates a list containing the elements of a stack.
332
+ *
333
+ * @param stack: The stack to convert
334
+ * @returns A list containing all stack values
335
+ *
336
+ * @example
337
+ * use Stack.{ module Immutable as Stack }
338
+ * let stack = Stack.empty
339
+ * let stack = Stack.push(1, stack)
340
+ * let stack = Stack.push(2, stack)
341
+ * assert Stack.toList(stack) == [2, 1]
342
+ *
343
+ * @since v0.7.0
344
+ */
345
+ provide let toList = stack => {
346
+ stack.data
347
+ }
348
+
349
+ /**
350
+ * Creates a stack from a list.
351
+ *
352
+ * @param list: The list to convert
353
+ * @returns A stack containing all list values
354
+ *
355
+ * @example
356
+ * use Stack.{ module Immutable as Stack }
357
+ * let stack = Stack.fromList([2, 1])
358
+ * assert Stack.peek(stack) == Some(2)
359
+ * let stack = Stack.pop(stack)
360
+ * assert Stack.peek(stack) == Some(1)
361
+ * let stack = Stack.pop(stack)
362
+ * assert Stack.isEmpty(stack)
363
+ *
364
+ * @since v0.7.0
365
+ */
366
+ provide let fromList = list => {
367
+ { data: list, }
368
+ }
369
+
370
+ /**
371
+ * Creates an array containing the elements of a stack.
372
+ *
373
+ * @param stack: The stack to convert
374
+ * @returns An array containing all stack values
375
+ *
376
+ * @example
377
+ * use Stack.{ module Immutable as Stack }
378
+ * let stack = Stack.empty
379
+ * let stack = Stack.push(1, stack)
380
+ * let stack = Stack.push(2, stack)
381
+ * assert Stack.toArray(stack) == [> 2, 1]
382
+ *
383
+ * @since v0.7.0
384
+ */
385
+ provide let toArray = stack => {
386
+ Array.fromList(stack.data)
387
+ }
388
+
389
+ /**
390
+ * Creates a stack from an array.
391
+ *
392
+ * @param arr: The array to convert
393
+ * @returns A stack containing all array values
394
+ *
395
+ * @example
396
+ * use Stack.{ module Immutable as Stack }
397
+ * let stack = Stack.fromArray([> 2, 1])
398
+ * assert Stack.peek(stack) == Some(2)
399
+ * let stack = Stack.pop(stack)
400
+ * assert Stack.peek(stack) == Some(1)
401
+ * let stack = Stack.pop(stack)
402
+ * assert Stack.isEmpty(stack)
403
+ *
404
+ * @since v0.7.0
405
+ */
406
+ provide let fromArray = arr => {
407
+ { data: Array.toList(arr), }
408
+ }
240
409
  }