ic-mops 0.8.4 → 0.8.5

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 (99) hide show
  1. package/.mops/base@0.7.4/LICENSE +208 -0
  2. package/.mops/base@0.7.4/README.md +64 -0
  3. package/.mops/base@0.7.4/mops.toml +5 -0
  4. package/.mops/base@0.7.4/src/Array.mo +686 -0
  5. package/.mops/base@0.7.4/src/AssocList.mo +203 -0
  6. package/.mops/base@0.7.4/src/Blob.mo +55 -0
  7. package/.mops/base@0.7.4/src/Bool.mo +44 -0
  8. package/.mops/base@0.7.4/src/Buffer.mo +1937 -0
  9. package/.mops/base@0.7.4/src/CertifiedData.mo +29 -0
  10. package/.mops/base@0.7.4/src/Char.mo +67 -0
  11. package/.mops/base@0.7.4/src/Debug.mo +15 -0
  12. package/.mops/base@0.7.4/src/Deque.mo +75 -0
  13. package/.mops/base@0.7.4/src/Error.mo +41 -0
  14. package/.mops/base@0.7.4/src/ExperimentalCycles.mo +51 -0
  15. package/.mops/base@0.7.4/src/ExperimentalInternetComputer.mo +36 -0
  16. package/.mops/base@0.7.4/src/ExperimentalStableMemory.mo +121 -0
  17. package/.mops/base@0.7.4/src/Float.mo +150 -0
  18. package/.mops/base@0.7.4/src/Func.mo +38 -0
  19. package/.mops/base@0.7.4/src/Hash.mo +83 -0
  20. package/.mops/base@0.7.4/src/HashMap.mo +229 -0
  21. package/.mops/base@0.7.4/src/Heap.mo +113 -0
  22. package/.mops/base@0.7.4/src/Int.mo +150 -0
  23. package/.mops/base@0.7.4/src/Int16.mo +159 -0
  24. package/.mops/base@0.7.4/src/Int32.mo +160 -0
  25. package/.mops/base@0.7.4/src/Int64.mo +161 -0
  26. package/.mops/base@0.7.4/src/Int8.mo +160 -0
  27. package/.mops/base@0.7.4/src/Iter.mo +220 -0
  28. package/.mops/base@0.7.4/src/IterType.mo +7 -0
  29. package/.mops/base@0.7.4/src/List.mo +433 -0
  30. package/.mops/base@0.7.4/src/Nat.mo +75 -0
  31. package/.mops/base@0.7.4/src/Nat16.mo +146 -0
  32. package/.mops/base@0.7.4/src/Nat32.mo +146 -0
  33. package/.mops/base@0.7.4/src/Nat64.mo +146 -0
  34. package/.mops/base@0.7.4/src/Nat8.mo +146 -0
  35. package/.mops/base@0.7.4/src/None.mo +19 -0
  36. package/.mops/base@0.7.4/src/Option.mo +160 -0
  37. package/.mops/base@0.7.4/src/Order.mo +46 -0
  38. package/.mops/base@0.7.4/src/Prelude.mo +33 -0
  39. package/.mops/base@0.7.4/src/Principal.mo +58 -0
  40. package/.mops/base@0.7.4/src/RBTree.mo +218 -0
  41. package/.mops/base@0.7.4/src/Random.mo +188 -0
  42. package/.mops/base@0.7.4/src/Result.mo +210 -0
  43. package/.mops/base@0.7.4/src/Stack.mo +40 -0
  44. package/.mops/base@0.7.4/src/Text.mo +615 -0
  45. package/.mops/base@0.7.4/src/Time.mo +37 -0
  46. package/.mops/base@0.7.4/src/Trie.mo +1200 -0
  47. package/.mops/base@0.7.4/src/TrieMap.mo +180 -0
  48. package/.mops/base@0.7.4/src/TrieSet.mo +97 -0
  49. package/.mops/base@0.8.3/LICENSE +208 -0
  50. package/.mops/base@0.8.3/README.md +64 -0
  51. package/.mops/base@0.8.3/mops.toml +6 -0
  52. package/.mops/base@0.8.3/src/Array.mo +717 -0
  53. package/.mops/base@0.8.3/src/AssocList.mo +404 -0
  54. package/.mops/base@0.8.3/src/Blob.mo +212 -0
  55. package/.mops/base@0.8.3/src/Bool.mo +44 -0
  56. package/.mops/base@0.8.3/src/Buffer.mo +2660 -0
  57. package/.mops/base@0.8.3/src/CertifiedData.mo +53 -0
  58. package/.mops/base@0.8.3/src/Char.mo +65 -0
  59. package/.mops/base@0.8.3/src/Debug.mo +56 -0
  60. package/.mops/base@0.8.3/src/Deque.mo +243 -0
  61. package/.mops/base@0.8.3/src/Error.mo +68 -0
  62. package/.mops/base@0.8.3/src/ExperimentalCycles.mo +151 -0
  63. package/.mops/base@0.8.3/src/ExperimentalInternetComputer.mo +60 -0
  64. package/.mops/base@0.8.3/src/ExperimentalStableMemory.mo +348 -0
  65. package/.mops/base@0.8.3/src/Float.mo +843 -0
  66. package/.mops/base@0.8.3/src/Func.mo +46 -0
  67. package/.mops/base@0.8.3/src/Hash.mo +82 -0
  68. package/.mops/base@0.8.3/src/HashMap.mo +457 -0
  69. package/.mops/base@0.8.3/src/Heap.mo +233 -0
  70. package/.mops/base@0.8.3/src/Int.mo +365 -0
  71. package/.mops/base@0.8.3/src/Int16.mo +521 -0
  72. package/.mops/base@0.8.3/src/Int32.mo +522 -0
  73. package/.mops/base@0.8.3/src/Int64.mo +522 -0
  74. package/.mops/base@0.8.3/src/Int8.mo +522 -0
  75. package/.mops/base@0.8.3/src/Iter.mo +227 -0
  76. package/.mops/base@0.8.3/src/IterType.mo +7 -0
  77. package/.mops/base@0.8.3/src/List.mo +930 -0
  78. package/.mops/base@0.8.3/src/Nat.mo +305 -0
  79. package/.mops/base@0.8.3/src/Nat16.mo +144 -0
  80. package/.mops/base@0.8.3/src/Nat32.mo +144 -0
  81. package/.mops/base@0.8.3/src/Nat64.mo +144 -0
  82. package/.mops/base@0.8.3/src/Nat8.mo +144 -0
  83. package/.mops/base@0.8.3/src/None.mo +19 -0
  84. package/.mops/base@0.8.3/src/Option.mo +154 -0
  85. package/.mops/base@0.8.3/src/Order.mo +46 -0
  86. package/.mops/base@0.8.3/src/Prelude.mo +33 -0
  87. package/.mops/base@0.8.3/src/Principal.mo +249 -0
  88. package/.mops/base@0.8.3/src/RBTree.mo +681 -0
  89. package/.mops/base@0.8.3/src/Random.mo +270 -0
  90. package/.mops/base@0.8.3/src/Result.mo +209 -0
  91. package/.mops/base@0.8.3/src/Stack.mo +93 -0
  92. package/.mops/base@0.8.3/src/Text.mo +761 -0
  93. package/.mops/base@0.8.3/src/Time.mo +36 -0
  94. package/.mops/base@0.8.3/src/Timer.mo +62 -0
  95. package/.mops/base@0.8.3/src/Trie.mo +1603 -0
  96. package/.mops/base@0.8.3/src/TrieMap.mo +392 -0
  97. package/.mops/base@0.8.3/src/TrieSet.mo +148 -0
  98. package/network.txt +1 -0
  99. package/package.json +2 -2
@@ -0,0 +1,717 @@
1
+ /// Provides extended utility functions on Arrays.
2
+ ///
3
+ /// Note the difference between mutable and non-mutable arrays below.
4
+ ///
5
+ /// WARNING: If you are looking for a list that can grow and shrink in size,
6
+ /// it is recommended you use either the Buffer class or the List class for
7
+ /// those purposes. Arrays must be created with a fixed size.
8
+ ///
9
+ /// Import from the base library to use this module.
10
+ /// ```motoko name=import
11
+ /// import Array "mo:base/Array";
12
+ /// ```
13
+
14
+ import I "IterType";
15
+ import Option "Option";
16
+ import Order "Order";
17
+ import Prim "mo:⛔";
18
+ import Result "Result";
19
+
20
+ module {
21
+ /// Create a mutable array with `size` copies of the initial value.
22
+ ///
23
+ /// ```motoko include=import
24
+ /// let array = Array.init<Nat>(4, 2);
25
+ /// ```
26
+ ///
27
+ /// Runtime: O(size)
28
+ /// Space: O(size)
29
+ public func init<X>(size : Nat, initValue : X) : [var X] = Prim.Array_init<X>(size, initValue);
30
+
31
+ /// Create an immutable array of size `size`. Each element at index i
32
+ /// is created by applying `generator` to i.
33
+ ///
34
+ /// ```motoko include=import
35
+ /// let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);
36
+ /// ```
37
+ ///
38
+ /// Runtime: O(size)
39
+ /// Space: O(size)
40
+ ///
41
+ /// *Runtime and space assumes that `generator` runs in O(1) time and space.
42
+ public func tabulate<X>(size : Nat, generator : Nat -> X) : [X] = Prim.Array_tabulate<X>(size, generator);
43
+
44
+ /// Create a mutable array of size `size`. Each element at index i
45
+ /// is created by applying `generator` to i.
46
+ ///
47
+ /// ```motoko include=import
48
+ /// let array : [var Nat] = Array.tabulateVar<Nat>(4, func i = i * 2);
49
+ /// array[2] := 0;
50
+ /// array
51
+ /// ```
52
+ ///
53
+ /// Runtime: O(size)
54
+ /// Space: O(size)
55
+ ///
56
+ /// *Runtime and space assumes that `generator` runs in O(1) time and space.
57
+ public func tabulateVar<X>(size : Nat, generator : Nat -> X) : [var X] {
58
+ // FIXME add this as a primitive in the RTS
59
+ if (size == 0) { return [var] };
60
+ let array = Prim.Array_init<X>(size, generator 0);
61
+ var i = 0;
62
+ while (i < size) {
63
+ array[i] := generator i;
64
+ i += 1
65
+ };
66
+ array
67
+ };
68
+
69
+ /// Transforms a mutable array into an immutable array.
70
+ ///
71
+ /// ```motoko include=import
72
+ ///
73
+ /// let varArray = [var 0, 1, 2];
74
+ /// varArray[2] := 3;
75
+ /// let array = Array.freeze<Nat>(varArray);
76
+ /// ```
77
+ ///
78
+ /// Runtime: O(size)
79
+ ///
80
+ /// Space: O(1)
81
+ public func freeze<X>(varArray : [var X]) : [X] = Prim.Array_tabulate<X>(varArray.size(), func i = varArray[i]);
82
+
83
+ /// Transforms an immutable array into a mutable array.
84
+ ///
85
+ /// ```motoko include=import
86
+ ///
87
+ /// let array = [0, 1, 2];
88
+ /// let varArray = Array.thaw<Nat>(array);
89
+ /// varArray[2] := 3;
90
+ /// varArray
91
+ /// ```
92
+ ///
93
+ /// Runtime: O(size)
94
+ ///
95
+ /// Space: O(1)
96
+ public func thaw<A>(array : [A]) : [var A] {
97
+ let size = array.size();
98
+ if (size == 0) {
99
+ return [var]
100
+ };
101
+ let newArray = Prim.Array_init<A>(size, array[0]);
102
+ var i = 0;
103
+ while (i < size) {
104
+ newArray[i] := array[i];
105
+ i += 1
106
+ };
107
+ newArray
108
+ };
109
+
110
+ /// Tests if two arrays contain equal values (i.e. they represent the same
111
+ /// list of elements). Uses `equal` to compare elements in the arrays.
112
+ ///
113
+ /// ```motoko include=import
114
+ /// // Use the equal function from the Nat module to compare Nats
115
+ /// import {equal} "mo:base/Nat";
116
+ ///
117
+ /// let array1 = [0, 1, 2, 3];
118
+ /// let array2 = [0, 1, 2, 3];
119
+ /// Array.equal(array1, array2, equal)
120
+ /// ```
121
+ ///
122
+ /// Runtime: O(size1 + size2)
123
+ ///
124
+ /// Space: O(1)
125
+ ///
126
+ /// *Runtime and space assumes that `equal` runs in O(1) time and space.
127
+ public func equal<X>(array1 : [X], array2 : [X], equal : (X, X) -> Bool) : Bool {
128
+ let size1 = array1.size();
129
+ let size2 = array2.size();
130
+ if (size1 != size2) {
131
+ return false
132
+ };
133
+ var i = 0;
134
+ while (i < size1) {
135
+ if (not equal(array1[i], array2[i])) {
136
+ return false
137
+ };
138
+ i += 1
139
+ };
140
+ return true
141
+ };
142
+
143
+ /// Returns the first value in `array` for which `predicate` returns true.
144
+ /// If no element satisfies the predicate, returns null.
145
+ ///
146
+ /// ```motoko include=import
147
+ /// let array = [1, 9, 4, 8];
148
+ /// Array.find<Nat>(array, func x = x > 8)
149
+ /// ```
150
+ /// Runtime: O(size)
151
+ ///
152
+ /// Space: O(1)
153
+ ///
154
+ /// *Runtime and space assumes that `predicate` runs in O(1) time and space.
155
+ public func find<X>(array : [X], predicate : X -> Bool) : ?X {
156
+ for (element in array.vals()) {
157
+ if (predicate element) {
158
+ return ?element
159
+ }
160
+ };
161
+ return null
162
+ };
163
+
164
+ /// Create a new array by appending the values of `array1` and `array2`.
165
+ /// @deprecated `Array.append` copies its arguments and has linear complexity;
166
+ /// when used in a loop, consider using a `Buffer`, and `Buffer.append`, instead.
167
+ ///
168
+ /// ```motoko include=import
169
+ /// let array1 = [1, 2, 3];
170
+ /// let array2 = [4, 5, 6];
171
+ /// Array.append<Nat>(array1, array2)
172
+ /// ```
173
+ /// Runtime: O(size1 + size2)
174
+ ///
175
+ /// Space: O(size1 + size2)
176
+ public func append<X>(array1 : [X], array2 : [X]) : [X] {
177
+ let size1 = array1.size();
178
+ let size2 = array2.size();
179
+ Prim.Array_tabulate<X>(
180
+ size1 + size2,
181
+ func i {
182
+ if (i < size1) {
183
+ array1[i]
184
+ } else {
185
+ array2[i - size1]
186
+ }
187
+ }
188
+ )
189
+ };
190
+
191
+ // FIXME this example stack overflows. Should test with new implementation of sortInPlace
192
+ /// Sorts the elements in the array according to `compare`.
193
+ /// Sort is deterministic and stable.
194
+ ///
195
+ /// ```motoko include=import
196
+ /// import Nat "mo:base/Nat";
197
+ ///
198
+ /// let array = [4, 2, 6];
199
+ /// Array.sort(array, Nat.compare)
200
+ /// ```
201
+ /// Runtime: O(size * log(size))
202
+ ///
203
+ /// Space: O(size)
204
+ /// *Runtime and space assumes that `compare` runs in O(1) time and space.
205
+ public func sort<X>(array : [X], compare : (X, X) -> Order.Order) : [X] {
206
+ let temp : [var X] = thaw(array);
207
+ sortInPlace(temp, compare);
208
+ freeze(temp)
209
+ };
210
+
211
+ /// Sorts the elements in the array, __in place__, according to `compare`.
212
+ /// Sort is deterministic, stable, and in-place.
213
+ ///
214
+ /// ```motoko include=import
215
+ ///
216
+ /// import {compare} "mo:base/Nat";
217
+ ///
218
+ /// let array = [var 4, 2, 6];
219
+ /// Array.sortInPlace(array, compare);
220
+ /// array
221
+ /// ```
222
+ /// Runtime: O(size * log(size))
223
+ ///
224
+ /// Space: O(size)
225
+ /// *Runtime and space assumes that `compare` runs in O(1) time and space.
226
+ public func sortInPlace<X>(array : [var X], compare : (X, X) -> Order.Order) {
227
+ // Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer.
228
+ let size = array.size();
229
+ if (size == 0) {
230
+ return
231
+ };
232
+ let scratchSpace = Prim.Array_init<X>(size, array[0]);
233
+
234
+ let sizeDec = size - 1 : Nat;
235
+ var currSize = 1; // current size of the subarrays being merged
236
+ // when the current size == size, the array has been merged into a single sorted array
237
+ while (currSize < size) {
238
+ var leftStart = 0; // selects the current left subarray being merged
239
+ while (leftStart < sizeDec) {
240
+ let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {
241
+ leftStart + currSize - 1
242
+ } else { sizeDec };
243
+ let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {
244
+ leftStart + (2 * currSize) - 1
245
+ } else { sizeDec };
246
+
247
+ // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]
248
+ var left = leftStart;
249
+ var right = mid + 1;
250
+ var nextSorted = leftStart;
251
+ while (left < mid + 1 and right < rightEnd + 1) {
252
+ let leftElement = array[left];
253
+ let rightElement = array[right];
254
+ switch (compare(leftElement, rightElement)) {
255
+ case (#less or #equal) {
256
+ scratchSpace[nextSorted] := leftElement;
257
+ left += 1
258
+ };
259
+ case (#greater) {
260
+ scratchSpace[nextSorted] := rightElement;
261
+ right += 1
262
+ }
263
+ };
264
+ nextSorted += 1
265
+ };
266
+ while (left < mid + 1) {
267
+ scratchSpace[nextSorted] := array[left];
268
+ nextSorted += 1;
269
+ left += 1
270
+ };
271
+ while (right < rightEnd + 1) {
272
+ scratchSpace[nextSorted] := array[right];
273
+ nextSorted += 1;
274
+ right += 1
275
+ };
276
+
277
+ // Copy over merged elements
278
+ var i = leftStart;
279
+ while (i < rightEnd + 1) {
280
+ array[i] := scratchSpace[i];
281
+ i += 1
282
+ };
283
+
284
+ leftStart += 2 * currSize
285
+ };
286
+ currSize *= 2
287
+ }
288
+ };
289
+
290
+ /// Creates a new array by reversing the order of elements in `array`.
291
+ ///
292
+ /// ```motoko include=import
293
+ ///
294
+ /// let array = [10, 11, 12];
295
+ ///
296
+ /// Array.reverse(array)
297
+ /// ```
298
+ ///
299
+ /// Runtime: O(size)
300
+ ///
301
+ /// Space: O(1)
302
+ public func reverse<X>(array : [X]) : [X] {
303
+ let size = array.size();
304
+ Prim.Array_tabulate<X>(size, func i = array[size - i - 1])
305
+ };
306
+
307
+ /// Creates a new array by applying `f` to each element in `array`. `f` "maps"
308
+ /// each element it is applied to of type `X` to an element of type `Y`.
309
+ /// Retains original ordering of elements.
310
+ ///
311
+ /// ```motoko include=import
312
+ ///
313
+ /// let array = [0, 1, 2, 3];
314
+ /// Array.map<Nat, Nat>(array, func x = x * 3)
315
+ /// ```
316
+ ///
317
+ /// Runtime: O(size)
318
+ ///
319
+ /// Space: O(size)
320
+ ///
321
+ /// *Runtime and space assumes that `f` runs in O(1) time and space.
322
+ public func map<X, Y>(array : [X], f : X -> Y) : [Y] = Prim.Array_tabulate<Y>(array.size(), func i = f(array[i]));
323
+
324
+ /// Creates a new array by applying `predicate` to every element
325
+ /// in `array`, retaining the elements for which `predicate` returns true.
326
+ ///
327
+ /// ```motoko include=import
328
+ /// let array = [4, 2, 6, 1, 5];
329
+ /// let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);
330
+ /// ```
331
+ /// Runtime: O(size)
332
+ ///
333
+ /// Space: O(size)
334
+ /// *Runtime and space assumes that `predicate` runs in O(1) time and space.
335
+ public func filter<X>(array : [X], predicate : X -> Bool) : [X] {
336
+ var count = 0;
337
+ let keep = Prim.Array_tabulate<Bool>(
338
+ array.size(),
339
+ func i {
340
+ if (predicate(array[i])) {
341
+ count += 1;
342
+ true
343
+ } else {
344
+ false
345
+ }
346
+ }
347
+ );
348
+ var nextKeep = 0;
349
+ Prim.Array_tabulate<X>(
350
+ count,
351
+ func _ {
352
+ while (not keep[nextKeep]) {
353
+ nextKeep += 1
354
+ };
355
+ nextKeep += 1;
356
+ array[nextKeep - 1]
357
+ }
358
+ )
359
+ };
360
+
361
+ // FIXME the arguments ordering to the higher order function are flipped
362
+ // between this and the buffer class
363
+ // probably can't avoid breaking changes at some point
364
+ /// Creates a new array by applying `f` to each element in `array` and its index.
365
+ /// Retains original ordering of elements.
366
+ ///
367
+ /// ```motoko include=import
368
+ ///
369
+ /// let array = [10, 10, 10, 10];
370
+ /// Array.mapEntries<Nat, Nat>(array, func (i, x) = i * x)
371
+ /// ```
372
+ ///
373
+ /// Runtime: O(size)
374
+ ///
375
+ /// Space: O(size)
376
+ ///
377
+ /// *Runtime and space assumes that `f` runs in O(1) time and space.
378
+ public func mapEntries<X, Y>(array : [X], f : (X, Nat) -> Y) : [Y] = Prim.Array_tabulate<Y>(array.size(), func i = f(array[i], i));
379
+
380
+ /// Creates a new array by applying `f` to each element in `array`,
381
+ /// and keeping all non-null elements. The ordering is retained.
382
+ ///
383
+ /// ```motoko include=import
384
+ /// import {toText} "mo:base/Nat";
385
+ ///
386
+ /// let array = [4, 2, 0, 1];
387
+ /// let newArray =
388
+ /// Array.mapFilter<Nat, Text>( // mapping from Nat to Text values
389
+ /// array,
390
+ /// func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null
391
+ /// );
392
+ /// ```
393
+ /// Runtime: O(size)
394
+ ///
395
+ /// Space: O(size)
396
+ /// *Runtime and space assumes that `f` runs in O(1) time and space.
397
+ public func mapFilter<X, Y>(array : [X], f : X -> ?Y) : [Y] {
398
+ var count = 0;
399
+ let options = Prim.Array_tabulate<?Y>(
400
+ array.size(),
401
+ func i {
402
+ let result = f(array[i]);
403
+ switch (result) {
404
+ case (?element) {
405
+ count += 1;
406
+ result
407
+ };
408
+ case null {
409
+ null
410
+ }
411
+ }
412
+ }
413
+ );
414
+
415
+ var nextSome = 0;
416
+ Prim.Array_tabulate<Y>(
417
+ count,
418
+ func _ {
419
+ while (Option.isNull(options[nextSome])) {
420
+ nextSome += 1
421
+ };
422
+ nextSome += 1;
423
+ switch (options[nextSome - 1]) {
424
+ case (?element) element;
425
+ case null {
426
+ Prim.trap "Malformed array in mapFilter"
427
+ }
428
+ }
429
+ }
430
+ )
431
+ };
432
+
433
+ /// Creates a new array by applying `f` to each element in `array`.
434
+ /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise
435
+ /// returns an `#ok` containing the new array.
436
+ ///
437
+ /// ```motoko include=import
438
+ /// let array = [4, 3, 2, 1, 0];
439
+ /// // divide 100 by every element in the array
440
+ /// Array.mapResult<Nat, Nat, Text>(array, func x {
441
+ /// if (x > 0) {
442
+ /// #ok(100 / x)
443
+ /// } else {
444
+ /// #err "Cannot divide by zero"
445
+ /// }
446
+ /// })
447
+ /// ```
448
+ ///
449
+ /// Runtime: O(size)
450
+ ///
451
+ /// Space: O(size)
452
+ ///
453
+ /// *Runtime and space assumes that `f` runs in O(1) time and space.
454
+ public func mapResult<X, Y, E>(array : [X], f : X -> Result.Result<Y, E>) : Result.Result<[Y], E> {
455
+ let size = array.size();
456
+ var target : [var Y] = [var];
457
+ var isInit = false;
458
+
459
+ var error : ?Result.Result<[Y], E> = null;
460
+ let results = Prim.Array_tabulate<?Y>(
461
+ size,
462
+ func i {
463
+ switch (f(array[i])) {
464
+ case (#ok element) {
465
+ ?element
466
+ };
467
+ case (#err e) {
468
+ switch (error) {
469
+ case null {
470
+ // only take the first error
471
+ error := ?(#err e)
472
+ };
473
+ case _ {}
474
+ };
475
+ null
476
+ }
477
+ }
478
+ }
479
+ );
480
+
481
+ switch error {
482
+ case null {
483
+ // unpack the option
484
+ #ok(
485
+ map<?Y, Y>(
486
+ results,
487
+ func element {
488
+ switch element {
489
+ case (?element) {
490
+ element
491
+ };
492
+ case null {
493
+ Prim.trap "Malformed array in mapResults"
494
+ }
495
+ }
496
+ }
497
+ )
498
+ )
499
+ };
500
+ case (?error) {
501
+ error
502
+ }
503
+ }
504
+ };
505
+
506
+ /// Creates a new array by applying `k` to each element in `array`,
507
+ /// and concatenating the resulting arrays in order. This operation
508
+ /// is similar to what in other functional languages is known as monadic bind.
509
+ ///
510
+ /// ```motoko include=import
511
+ /// import Nat "mo:base/Nat";
512
+ ///
513
+ /// let array = [1, 2, 3, 4];
514
+ /// Array.chain<Nat, Int>(array, func x = [x, -x])
515
+ ///
516
+ /// ```
517
+ /// Runtime: O(size)
518
+ ///
519
+ /// Space: O(size)
520
+ /// *Runtime and space assumes that `k` runs in O(1) time and space.
521
+ public func chain<X, Y>(array : [X], k : X -> [Y]) : [Y] {
522
+ var flatSize = 0;
523
+ let subArrays = Prim.Array_tabulate<[Y]>(
524
+ array.size(),
525
+ func i {
526
+ let subArray = k(array[i]);
527
+ flatSize += subArray.size();
528
+ subArray
529
+ }
530
+ );
531
+ // could replace with a call to flatten,
532
+ // but it would require an extra pass (to compute `flatSize`)
533
+ var outer = 0;
534
+ var inner = 0;
535
+ Prim.Array_tabulate<Y>(
536
+ flatSize,
537
+ func _ {
538
+ let subArray = subArrays[outer];
539
+ let element = subArray[inner];
540
+ inner += 1;
541
+ if (inner == subArray.size()) {
542
+ inner := 0;
543
+ outer += 1
544
+ };
545
+ element
546
+ }
547
+ )
548
+ };
549
+
550
+ /// Collapses the elements in `array` into a single value by starting with `base`
551
+ /// and progessively combining elements into `base` with `combine`. Iteration runs
552
+ /// left to right.
553
+ ///
554
+ /// ```motoko include=import
555
+ /// import {add} "mo:base/Nat";
556
+ ///
557
+ /// let array = [4, 2, 0, 1];
558
+ /// let sum =
559
+ /// Array.foldLeft<Nat, Nat>(
560
+ /// array,
561
+ /// 0, // start the sum at 0
562
+ /// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!
563
+ /// );
564
+ /// ```
565
+ ///
566
+ /// Runtime: O(size)
567
+ ///
568
+ /// Space: O(1)
569
+ ///
570
+ /// *Runtime and space assumes that `combine` runs in O(1) time and space.
571
+ public func foldLeft<X, A>(array : [X], base : A, combine : (A, X) -> A) : A {
572
+ var accumulation = base;
573
+
574
+ for (element in array.vals()) {
575
+ accumulation := combine(accumulation, element)
576
+ };
577
+
578
+ accumulation
579
+ };
580
+
581
+ // FIXME the type arguments are reverse order from Buffer
582
+ /// Collapses the elements in `array` into a single value by starting with `base`
583
+ /// and progessively combining elements into `base` with `combine`. Iteration runs
584
+ /// right to left.
585
+ ///
586
+ /// ```motoko include=import
587
+ /// import {toText} "mo:base/Nat";
588
+ ///
589
+ /// let array = [1, 9, 4, 8];
590
+ /// let bookTitle = Array.foldRight<Nat, Text>(array, "", func(x, acc) = toText(x) # acc);
591
+ /// ```
592
+ ///
593
+ /// Runtime: O(size)
594
+ ///
595
+ /// Space: O(1)
596
+ ///
597
+ /// *Runtime and space assumes that `combine` runs in O(1) time and space.
598
+ public func foldRight<X, A>(array : [X], base : A, combine : (X, A) -> A) : A {
599
+ var accumulation = base;
600
+ let size = array.size();
601
+
602
+ var i = size;
603
+ while (i > 0) {
604
+ i -= 1;
605
+ accumulation := combine(array[i], accumulation)
606
+ };
607
+
608
+ accumulation
609
+ };
610
+
611
+ /// Flattens the array of arrays into a single array. Retains the original
612
+ /// ordering of the elements.
613
+ ///
614
+ /// ```motoko include=import
615
+ ///
616
+ /// let arrays = [[0, 1, 2], [2, 3], [], [4]];
617
+ /// Array.flatten<Nat>(arrays)
618
+ /// ```
619
+ ///
620
+ /// Runtime: O(number of elements in array)
621
+ ///
622
+ /// Space: O(number of elements in array)
623
+ public func flatten<X>(arrays : [[X]]) : [X] {
624
+ var flatSize = 0;
625
+ for (subArray in arrays.vals()) {
626
+ flatSize += subArray.size()
627
+ };
628
+
629
+ var outer = 0;
630
+ var inner = 0;
631
+ Prim.Array_tabulate<X>(
632
+ flatSize,
633
+ func _ {
634
+ while (inner == arrays[outer].size()) {
635
+ inner := 0;
636
+ outer += 1
637
+ };
638
+ let element = arrays[outer][inner];
639
+ inner += 1;
640
+ element
641
+ }
642
+ )
643
+ };
644
+
645
+ /// Create an array containing a single value.
646
+ ///
647
+ /// ```motoko include=import
648
+ /// Array.make(2)
649
+ /// ```
650
+ ///
651
+ /// Runtime: O(1)
652
+ ///
653
+ /// Space: O(1)
654
+ public func make<X>(element : X) : [X] = [element];
655
+
656
+ /// Returns an Iterator (`Iter`) over the elements of `array`.
657
+ /// Iterator provides a single method `next()`, which returns
658
+ /// elements in order, or `null` when out of elements to iterate over.
659
+ ///
660
+ /// NOTE: You can also use `array.vals()` instead of this function. See example
661
+ /// below.
662
+ ///
663
+ /// ```motoko include=import
664
+ ///
665
+ /// let array = [10, 11, 12];
666
+ ///
667
+ /// var sum = 0;
668
+ /// for (element in array.vals()) {
669
+ /// sum += element;
670
+ /// };
671
+ /// sum
672
+ /// ```
673
+ ///
674
+ /// Runtime: O(1)
675
+ ///
676
+ /// Space: O(1)
677
+ public func vals<X>(array : [X]) : I.Iter<X> = array.vals();
678
+
679
+ /// Returns an Iterator (`Iter`) over the indices of `array`.
680
+ /// Iterator provides a single method `next()`, which returns
681
+ /// indices in order, or `null` when out of index to iterate over.
682
+ ///
683
+ /// NOTE: You can also use `array.keys()` instead of this function. See example
684
+ /// below.
685
+ ///
686
+ /// ```motoko include=import
687
+ ///
688
+ /// let array = [10, 11, 12];
689
+ ///
690
+ /// var sum = 0;
691
+ /// for (element in array.keys()) {
692
+ /// sum += element;
693
+ /// };
694
+ /// sum
695
+ /// ```
696
+ ///
697
+ /// Runtime: O(1)
698
+ ///
699
+ /// Space: O(1)
700
+ public func keys<X>(array : [X]) : I.Iter<Nat> = array.keys();
701
+
702
+ /// Returns the size of `array`.
703
+ ///
704
+ /// NOTE: You can also use `array.size()` instead of this function. See example
705
+ /// below.
706
+ ///
707
+ /// ```motoko include=import
708
+ ///
709
+ /// let array = [10, 11, 12];
710
+ /// let size = Array.size(array);
711
+ /// ```
712
+ ///
713
+ /// Runtime: O(1)
714
+ ///
715
+ /// Space: O(1)
716
+ public func size<X>(array : [X]) : Nat = array.size()
717
+ }