ic-mops 0.8.5 → 0.8.7

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/package.json +3 -1
  2. package/.mops/base@0.7.4/LICENSE +0 -208
  3. package/.mops/base@0.7.4/README.md +0 -64
  4. package/.mops/base@0.7.4/mops.toml +0 -5
  5. package/.mops/base@0.7.4/src/Array.mo +0 -686
  6. package/.mops/base@0.7.4/src/AssocList.mo +0 -203
  7. package/.mops/base@0.7.4/src/Blob.mo +0 -55
  8. package/.mops/base@0.7.4/src/Bool.mo +0 -44
  9. package/.mops/base@0.7.4/src/Buffer.mo +0 -1937
  10. package/.mops/base@0.7.4/src/CertifiedData.mo +0 -29
  11. package/.mops/base@0.7.4/src/Char.mo +0 -67
  12. package/.mops/base@0.7.4/src/Debug.mo +0 -15
  13. package/.mops/base@0.7.4/src/Deque.mo +0 -75
  14. package/.mops/base@0.7.4/src/Error.mo +0 -41
  15. package/.mops/base@0.7.4/src/ExperimentalCycles.mo +0 -51
  16. package/.mops/base@0.7.4/src/ExperimentalInternetComputer.mo +0 -36
  17. package/.mops/base@0.7.4/src/ExperimentalStableMemory.mo +0 -121
  18. package/.mops/base@0.7.4/src/Float.mo +0 -150
  19. package/.mops/base@0.7.4/src/Func.mo +0 -38
  20. package/.mops/base@0.7.4/src/Hash.mo +0 -83
  21. package/.mops/base@0.7.4/src/HashMap.mo +0 -229
  22. package/.mops/base@0.7.4/src/Heap.mo +0 -113
  23. package/.mops/base@0.7.4/src/Int.mo +0 -150
  24. package/.mops/base@0.7.4/src/Int16.mo +0 -159
  25. package/.mops/base@0.7.4/src/Int32.mo +0 -160
  26. package/.mops/base@0.7.4/src/Int64.mo +0 -161
  27. package/.mops/base@0.7.4/src/Int8.mo +0 -160
  28. package/.mops/base@0.7.4/src/Iter.mo +0 -220
  29. package/.mops/base@0.7.4/src/IterType.mo +0 -7
  30. package/.mops/base@0.7.4/src/List.mo +0 -433
  31. package/.mops/base@0.7.4/src/Nat.mo +0 -75
  32. package/.mops/base@0.7.4/src/Nat16.mo +0 -146
  33. package/.mops/base@0.7.4/src/Nat32.mo +0 -146
  34. package/.mops/base@0.7.4/src/Nat64.mo +0 -146
  35. package/.mops/base@0.7.4/src/Nat8.mo +0 -146
  36. package/.mops/base@0.7.4/src/None.mo +0 -19
  37. package/.mops/base@0.7.4/src/Option.mo +0 -160
  38. package/.mops/base@0.7.4/src/Order.mo +0 -46
  39. package/.mops/base@0.7.4/src/Prelude.mo +0 -33
  40. package/.mops/base@0.7.4/src/Principal.mo +0 -58
  41. package/.mops/base@0.7.4/src/RBTree.mo +0 -218
  42. package/.mops/base@0.7.4/src/Random.mo +0 -188
  43. package/.mops/base@0.7.4/src/Result.mo +0 -210
  44. package/.mops/base@0.7.4/src/Stack.mo +0 -40
  45. package/.mops/base@0.7.4/src/Text.mo +0 -615
  46. package/.mops/base@0.7.4/src/Time.mo +0 -37
  47. package/.mops/base@0.7.4/src/Trie.mo +0 -1200
  48. package/.mops/base@0.7.4/src/TrieMap.mo +0 -180
  49. package/.mops/base@0.7.4/src/TrieSet.mo +0 -97
  50. package/.mops/base@0.8.3/LICENSE +0 -208
  51. package/.mops/base@0.8.3/README.md +0 -64
  52. package/.mops/base@0.8.3/mops.toml +0 -6
  53. package/.mops/base@0.8.3/src/Array.mo +0 -717
  54. package/.mops/base@0.8.3/src/AssocList.mo +0 -404
  55. package/.mops/base@0.8.3/src/Blob.mo +0 -212
  56. package/.mops/base@0.8.3/src/Bool.mo +0 -44
  57. package/.mops/base@0.8.3/src/Buffer.mo +0 -2660
  58. package/.mops/base@0.8.3/src/CertifiedData.mo +0 -53
  59. package/.mops/base@0.8.3/src/Char.mo +0 -65
  60. package/.mops/base@0.8.3/src/Debug.mo +0 -56
  61. package/.mops/base@0.8.3/src/Deque.mo +0 -243
  62. package/.mops/base@0.8.3/src/Error.mo +0 -68
  63. package/.mops/base@0.8.3/src/ExperimentalCycles.mo +0 -151
  64. package/.mops/base@0.8.3/src/ExperimentalInternetComputer.mo +0 -60
  65. package/.mops/base@0.8.3/src/ExperimentalStableMemory.mo +0 -348
  66. package/.mops/base@0.8.3/src/Float.mo +0 -843
  67. package/.mops/base@0.8.3/src/Func.mo +0 -46
  68. package/.mops/base@0.8.3/src/Hash.mo +0 -82
  69. package/.mops/base@0.8.3/src/HashMap.mo +0 -457
  70. package/.mops/base@0.8.3/src/Heap.mo +0 -233
  71. package/.mops/base@0.8.3/src/Int.mo +0 -365
  72. package/.mops/base@0.8.3/src/Int16.mo +0 -521
  73. package/.mops/base@0.8.3/src/Int32.mo +0 -522
  74. package/.mops/base@0.8.3/src/Int64.mo +0 -522
  75. package/.mops/base@0.8.3/src/Int8.mo +0 -522
  76. package/.mops/base@0.8.3/src/Iter.mo +0 -227
  77. package/.mops/base@0.8.3/src/IterType.mo +0 -7
  78. package/.mops/base@0.8.3/src/List.mo +0 -930
  79. package/.mops/base@0.8.3/src/Nat.mo +0 -305
  80. package/.mops/base@0.8.3/src/Nat16.mo +0 -144
  81. package/.mops/base@0.8.3/src/Nat32.mo +0 -144
  82. package/.mops/base@0.8.3/src/Nat64.mo +0 -144
  83. package/.mops/base@0.8.3/src/Nat8.mo +0 -144
  84. package/.mops/base@0.8.3/src/None.mo +0 -19
  85. package/.mops/base@0.8.3/src/Option.mo +0 -154
  86. package/.mops/base@0.8.3/src/Order.mo +0 -46
  87. package/.mops/base@0.8.3/src/Prelude.mo +0 -33
  88. package/.mops/base@0.8.3/src/Principal.mo +0 -249
  89. package/.mops/base@0.8.3/src/RBTree.mo +0 -681
  90. package/.mops/base@0.8.3/src/Random.mo +0 -270
  91. package/.mops/base@0.8.3/src/Result.mo +0 -209
  92. package/.mops/base@0.8.3/src/Stack.mo +0 -93
  93. package/.mops/base@0.8.3/src/Text.mo +0 -761
  94. package/.mops/base@0.8.3/src/Time.mo +0 -36
  95. package/.mops/base@0.8.3/src/Timer.mo +0 -62
  96. package/.mops/base@0.8.3/src/Trie.mo +0 -1603
  97. package/.mops/base@0.8.3/src/TrieMap.mo +0 -392
  98. package/.mops/base@0.8.3/src/TrieSet.mo +0 -148
  99. package/network.txt +0 -1
@@ -1,930 +0,0 @@
1
- /// Purely-functional, singly-linked lists.
2
-
3
- /// A list of type `List<T>` is either `null` or an optional pair of a value of type `T` and a tail, itself of type `List<T>`.
4
- ///
5
- /// To use this library, import it using:
6
- ///
7
- /// ```motoko name=initialize
8
- /// import List "mo:base/List";
9
- /// ```
10
-
11
- import Array "Array";
12
- import Iter "IterType";
13
- import Option "Option";
14
- import Order "Order";
15
- import Result "Result";
16
-
17
- module {
18
-
19
- // A singly-linked list consists of zero or more _cons cells_, wherein
20
- // each cell contains a single list element (the cell's _head_), and a pointer to the
21
- // remainder of the list (the cell's _tail_).
22
- public type List<T> = ?(T, List<T>);
23
-
24
- /// Create an empty list.
25
- ///
26
- /// Example:
27
- /// ```motoko include=initialize
28
- /// List.nil<Nat>() // => null
29
- /// ```
30
- ///
31
- /// Runtime: O(1)
32
- ///
33
- /// Space: O(1)
34
- public func nil<T>() : List<T> = null;
35
-
36
- /// Check whether a list is empty and return true if the list is empty.
37
- ///
38
- /// Example:
39
- /// ```motoko include=initialize
40
- /// List.isNil<Nat>(null) // => true
41
- /// ```
42
- ///
43
- /// Runtime: O(1)
44
- ///
45
- /// Space: O(1)
46
- public func isNil<T>(l : List<T>) : Bool {
47
- switch l {
48
- case null { true };
49
- case _ { false }
50
- }
51
- };
52
-
53
- /// Add `x` to the head of `list`, and return the new list.
54
- ///
55
- /// Example:
56
- /// ```motoko include=initialize
57
- /// List.push<Nat>(0, null) // => ?(0, null);
58
- /// ```
59
- ///
60
- /// Runtime: O(1)
61
- ///
62
- /// Space: O(1)
63
- public func push<T>(x : T, l : List<T>) : List<T> = ?(x, l);
64
-
65
- /// Return the last element of the list, if present.
66
- /// Example:
67
- /// ```motoko include=initialize
68
- /// List.last<Nat>(?(0, ?(1, null))) // => ?1
69
- /// ```
70
- ///
71
- /// Runtime: O(size)
72
- ///
73
- /// Space: O(1)
74
- public func last<T>(l : List<T>) : ?T {
75
- switch l {
76
- case null { null };
77
- case (?(x, null)) { ?x };
78
- case (?(_, t)) { last<T>(t) }
79
- }
80
- };
81
-
82
- /// Remove the head of the list, returning the optioned head and the tail of the list in a pair.
83
- /// Returns `(null, null)` if the list is empty.
84
- ///
85
- /// Example:
86
- /// ```motoko include=initialize
87
- /// List.pop<Nat>(?(0, ?(1, null))) // => (?0, ?(1, null))
88
- /// ```
89
- ///
90
- /// Runtime: O(1)
91
- ///
92
- /// Space: O(1)
93
- public func pop<T>(l : List<T>) : (?T, List<T>) {
94
- switch l {
95
- case null { (null, null) };
96
- case (?(h, t)) { (?h, t) }
97
- }
98
- };
99
-
100
- /// Return the length of the list.
101
- ///
102
- /// Example:
103
- /// ```motoko include=initialize
104
- /// List.size<Nat>(?(0, ?(1, null))) // => 2
105
- /// ```
106
- ///
107
- /// Runtime: O(size)
108
- ///
109
- /// Space: O(1)
110
- public func size<T>(l : List<T>) : Nat {
111
- func rec(l : List<T>, n : Nat) : Nat {
112
- switch l {
113
- case null { n };
114
- case (?(_, t)) { rec(t, n + 1) }
115
- }
116
- };
117
- rec(l, 0)
118
- };
119
- /// Access any item in a list, zero-based.
120
- ///
121
- /// NOTE: Indexing into a list is a linear operation, and usually an
122
- /// indication that a list might not be the best data structure
123
- /// to use.
124
- ///
125
- /// Example:
126
- /// ```motoko include=initialize
127
- /// List.get<Nat>(?(0, ?(1, null)), 1) // => ?1
128
- /// ```
129
- ///
130
- /// Runtime: O(size)
131
- ///
132
- /// Space: O(1)
133
- public func get<T>(l : List<T>, n : Nat) : ?T {
134
- switch (n, l) {
135
- case (_, null) { null };
136
- case (0, (?(h, t))) { ?h };
137
- case (_, (?(_, t))) { get<T>(t, n - 1) }
138
- }
139
- };
140
-
141
- /// Reverses the list.
142
- ///
143
- /// Example:
144
- /// ```motoko include=initialize
145
- /// List.reverse<Nat>(?(0, ?(1, ?(2, null)))) // => ?(2, ?(1, ?(0, null)))
146
- /// ```
147
- ///
148
- /// Runtime: O(size)
149
- ///
150
- /// Space: O(size)
151
- public func reverse<T>(l : List<T>) : List<T> {
152
- func rec(l : List<T>, r : List<T>) : List<T> {
153
- switch l {
154
- case null { r };
155
- case (?(h, t)) { rec(t, ?(h, r)) }
156
- }
157
- };
158
- rec(l, null)
159
- };
160
-
161
- /// Call the given function for its side effect, with each list element in turn.
162
- ///
163
- /// Example:
164
- /// ```motoko include=initialize
165
- /// var sum = 0;
166
- /// List.iterate<Nat>(?(0, ?(1, ?(2, null))), func n { sum += n });
167
- /// sum // => 3
168
- /// ```
169
- ///
170
- /// Runtime: O(size)
171
- ///
172
- /// Space: O(1)
173
- public func iterate<T>(l : List<T>, f : T -> ()) {
174
- switch l {
175
- case null { () };
176
- case (?(h, t)) { f(h); iterate<T>(t, f) }
177
- }
178
- };
179
-
180
- /// Call the given function `f` on each list element and collect the results
181
- /// in a new list.
182
- ///
183
- /// Example:
184
- /// ```motoko include=initialize
185
- /// import Nat = "mo:base/Nat"
186
- /// List.map<Nat, Text>(?(0, ?(1, ?(2, null))), Nat.toText) // => ?("0", ?("1", ?("2", null))
187
- /// ```
188
- ///
189
- /// Runtime: O(size)
190
- ///
191
- /// Space: O(size)
192
- /// *Runtime and space assumes that `f` runs in O(1) time and space.
193
- public func map<T, U>(l : List<T>, f : T -> U) : List<U> {
194
- switch l {
195
- case null { null };
196
- case (?(h, t)) { ?(f(h), map<T, U>(t, f)) }
197
- }
198
- };
199
-
200
- /// Create a new list with only those elements of the original list for which
201
- /// the given function (often called the _predicate_) returns true.
202
- ///
203
- /// Example:
204
- /// ```motoko include=initialize
205
- /// List.filter<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => ?(0, ?(2, null))
206
- /// ```
207
- ///
208
- /// Runtime: O(size)
209
- ///
210
- /// Space: O(size)
211
- public func filter<T>(l : List<T>, f : T -> Bool) : List<T> {
212
- switch l {
213
- case null { null };
214
- case (?(h, t)) {
215
- if (f(h)) {
216
- ?(h, filter<T>(t, f))
217
- } else {
218
- filter<T>(t, f)
219
- }
220
- }
221
- }
222
- };
223
-
224
- /// Create two new lists from the results of a given function (`f`).
225
- /// The first list only includes the elements for which the given
226
- /// function `f` returns true and the second list only includes
227
- /// the elements for which the function returns false.
228
- ///
229
- /// Example:
230
- /// ```motoko include=initialize
231
- /// List.partition<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => (?(0, ?(2, null)), ?(1, null))
232
- /// ```
233
- ///
234
- /// Runtime: O(size)
235
- ///
236
- /// Space: O(size)
237
- public func partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>) {
238
- switch l {
239
- case null { (null, null) };
240
- case (?(h, t)) {
241
- if (f(h)) {
242
- // call f in-order
243
- let (l, r) = partition<T>(t, f);
244
- (?(h, l), r)
245
- } else {
246
- let (l, r) = partition<T>(t, f);
247
- (l, ?(h, r))
248
- }
249
- }
250
- }
251
- };
252
-
253
- /// Call the given function on each list element, and collect the non-null results
254
- /// in a new list.
255
- ///
256
- /// Example:
257
- /// ```motoko include=initialize
258
- /// List.mapFilter<Nat, Nat>(
259
- /// ?(1, ?(2, ?(3, null))),
260
- /// func n {
261
- /// if (n > 1) {
262
- /// ?(n * 2);
263
- /// } else {
264
- /// null
265
- /// }
266
- /// }
267
- /// ) // => ?(4, ?(6, null))
268
- /// ```
269
- ///
270
- /// Runtime: O(size)
271
- ///
272
- /// Space: O(size)
273
- public func mapFilter<T, U>(l : List<T>, f : T -> ?U) : List<U> {
274
- switch l {
275
- case null { null };
276
- case (?(h, t)) {
277
- switch (f(h)) {
278
- case null { mapFilter<T, U>(t, f) };
279
- case (?h_) { ?(h_, mapFilter<T, U>(t, f)) }
280
- }
281
- }
282
- }
283
- };
284
-
285
- /// Maps a Result-returning function `f` over a List and returns either
286
- /// the first error or a list of successful values.
287
- ///
288
- /// Example:
289
- /// ```motoko include=initialize
290
- /// List.mapResult<Nat, Nat, Text>(
291
- /// ?(1, ?(2, ?(3, null))),
292
- /// func n {
293
- /// if (n > 0) {
294
- /// #ok(n * 2);
295
- /// } else {
296
- /// #err("Some element is zero")
297
- /// }
298
- /// }
299
- /// ); // => #ok ?(2, ?(4, ?(6, null))
300
- /// ```
301
- ///
302
- /// Runtime: O(size)
303
- ///
304
- /// Space: O(size)
305
- ///
306
- /// *Runtime and space assumes that `f` runs in O(1) time and space.
307
- public func mapResult<T, R, E>(xs : List<T>, f : T -> Result.Result<R, E>) : Result.Result<List<R>, E> {
308
- func go(xs : List<T>, acc : List<R>) : Result.Result<List<R>, E> {
309
- switch xs {
310
- case null { #ok(acc) };
311
- case (?(head, tail)) {
312
- switch (f(head)) {
313
- case (#err(err)) { #err(err) };
314
- case (#ok(ok)) { go(tail, ?(ok, acc)) }
315
- }
316
- }
317
- }
318
- };
319
- Result.mapOk(go(xs, null), func(xs : List<R>) : List<R> = reverse(xs))
320
- };
321
-
322
- /// Append the elements from the reverse of one list, 'l', to another list, 'm'.
323
- ///
324
- /// Example:
325
- /// ```motoko include=initialize
326
- /// List.revAppend<Nat>(
327
- /// ?(2, ?(1, ?(0, null))),
328
- /// ?(3, ?(4, ?(5, null)))
329
- /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))
330
- /// ```
331
- ///
332
- /// Runtime: O(size(l))
333
- ///
334
- /// Space: O(size(l))
335
- func revAppend<T>(l : List<T>, m : List<T>) : List<T> {
336
- switch l {
337
- case null { m };
338
- case (?(h, t)) { revAppend(t, ?(h, m)) }
339
- }
340
- };
341
-
342
- /// Append the elements from one list to another list.
343
- ///
344
- /// Example:
345
- /// ```motoko include=initialize
346
- /// List.append<Nat>(
347
- /// ?(0, ?(1, ?(2, null))),
348
- /// ?(3, ?(4, ?(5, null)))
349
- /// ) // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))
350
- /// ```
351
- ///
352
- /// Runtime: O(size(l))
353
- ///
354
- /// Space: O(size(l))
355
- public func append<T>(l : List<T>, m : List<T>) : List<T> {
356
- revAppend(reverse(l), m)
357
- };
358
-
359
- /// Flatten, or concatenate, a list of lists as a list.
360
- ///
361
- /// Example:
362
- /// ```motoko include=initialize
363
- /// List.flatten<Nat>(
364
- /// ?(?(0, ?(1, ?(2, null))),
365
- /// ?(?(3, ?(4, ?(5, null))),
366
- /// null))
367
- /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))
368
- /// ```
369
- ///
370
- /// Runtime: O(size*size)
371
- ///
372
- /// Space: O(size*size)
373
- public func flatten<T>(l : List<List<T>>) : List<T> {
374
- //FIXME: this is quadratic, not linear https://github.com/dfinity/motoko-base/issues/459
375
- foldLeft<List<T>, List<T>>(l, null, func(a, b) { append<T>(a, b) })
376
- };
377
-
378
- /// Returns the first `n` elements of the given list.
379
- /// If the given list has fewer than `n` elements, this function returns
380
- /// a copy of the full input list.
381
- ///
382
- /// Example:
383
- /// ```motoko include=initialize
384
- /// List.take<Nat>(
385
- /// ?(0, ?(1, ?(2, null))),
386
- /// 2
387
- /// ); // => ?(0, ?(1, null))
388
- /// ```
389
- ///
390
- /// Runtime: O(n)
391
- ///
392
- /// Space: O(n)
393
- public func take<T>(l : List<T>, n : Nat) : List<T> {
394
- switch (l, n) {
395
- case (_, 0) { null };
396
- case (null, _) { null };
397
- case (?(h, t), m) { ?(h, take<T>(t, m - 1)) }
398
- }
399
- };
400
-
401
- /// Drop the first `n` elements from the given list.
402
- ///
403
- /// Example:
404
- /// ```motoko include=initialize
405
- /// List.drop<Nat>(
406
- /// ?(0, ?(1, ?(2, null))),
407
- /// 2
408
- /// ); // => ?(2, null)
409
- /// ```
410
- ///
411
- /// Runtime: O(n)
412
- ///
413
- /// Space: O(1)
414
- public func drop<T>(l : List<T>, n : Nat) : List<T> {
415
- switch (l, n) {
416
- case (l_, 0) { l_ };
417
- case (null, _) { null };
418
- case ((?(h, t)), m) { drop<T>(t, m - 1) }
419
- }
420
- };
421
-
422
- /// Collapses the elements in `list` into a single value by starting with `base`
423
- /// and progessively combining elements into `base` with `combine`. Iteration runs
424
- /// left to right.
425
- ///
426
- /// Example:
427
- /// ```motoko include=initialize
428
- /// import Nat "mo:base/Nat";
429
- ///
430
- /// List.foldLeft<Nat, Text>(
431
- /// ?(1, ?(2, ?(3, null))),
432
- /// "",
433
- /// func (acc, x) { acc # Nat.toText(x)}
434
- /// ) // => "123"
435
- /// ```
436
- ///
437
- /// Runtime: O(size(list))
438
- ///
439
- /// Space: O(1) heap, O(1) stack
440
- ///
441
- /// *Runtime and space assumes that `combine` runs in O(1) time and space.
442
- public func foldLeft<T, S>(list : List<T>, base : S, combine : (S, T) -> S) : S {
443
- switch list {
444
- case null { base };
445
- case (?(h, t)) { foldLeft(t, combine(base, h), combine) }
446
- }
447
- };
448
-
449
- /// Collapses the elements in `buffer` into a single value by starting with `base`
450
- /// and progessively combining elements into `base` with `combine`. Iteration runs
451
- /// right to left.
452
- ///
453
- /// Example:
454
- /// ```motoko include=initialize
455
- /// import Nat "mo:base/Nat";
456
- ///
457
- /// List.foldRight<Nat, Text>(
458
- /// ?(1, ?(2, ?(3, null))),
459
- /// "",
460
- /// func (x, acc) { Nat.toText(x) # acc}
461
- /// ) // => "123"
462
- /// ```
463
- ///
464
- /// Runtime: O(size(list))
465
- ///
466
- /// Space: O(1) heap, O(size(list)) stack
467
- ///
468
- /// *Runtime and space assumes that `combine` runs in O(1) time and space.
469
- public func foldRight<T, S>(list : List<T>, base : S, combine : (T, S) -> S) : S {
470
- switch list {
471
- case null { base };
472
- case (?(h, t)) { combine(h, foldRight<T, S>(t, base, combine)) }
473
- }
474
- };
475
-
476
- /// Return the first element for which the given predicate `f` is true,
477
- /// if such an element exists.
478
- ///
479
- /// Example:
480
- /// ```motoko include=initialize
481
- ///
482
- /// List.find<Nat>(
483
- /// ?(1, ?(2, ?(3, null))),
484
- /// func n { n > 1 }
485
- /// ); // => ?2
486
- /// ```
487
- ///
488
- /// Runtime: O(size)
489
- ///
490
- /// Space: O(1)
491
- ///
492
- /// *Runtime and space assumes that `f` runs in O(1) time and space.
493
- public func find<T>(l : List<T>, f : T -> Bool) : ?T {
494
- switch l {
495
- case null { null };
496
- case (?(h, t)) { if (f(h)) { ?h } else { find<T>(t, f) } }
497
- }
498
- };
499
-
500
- /// Return true if there exists a list element for which
501
- /// the given predicate `f` is true.
502
- ///
503
- /// Example:
504
- /// ```motoko include=initialize
505
- ///
506
- /// List.some<Nat>(
507
- /// ?(1, ?(2, ?(3, null))),
508
- /// func n { n > 1 }
509
- /// ) // => true
510
- /// ```
511
- ///
512
- /// Runtime: O(size(list))
513
- ///
514
- /// Space: O(1)
515
- ///
516
- /// *Runtime and space assumes that `f` runs in O(1) time and space.
517
- public func some<T>(l : List<T>, f : T -> Bool) : Bool {
518
- switch l {
519
- case null { false };
520
- case (?(h, t)) { f(h) or some<T>(t, f) }
521
- }
522
- };
523
-
524
- /// Return true if the given predicate `f` is true for all list
525
- /// elements.
526
- ///
527
- /// Example:
528
- /// ```motoko include=initialize
529
- ///
530
- /// List.all<Nat>(
531
- /// ?(1, ?(2, ?(3, null))),
532
- /// func n { n > 1 }
533
- /// ); // => false
534
- /// ```
535
- ///
536
- /// Runtime: O(size)
537
- ///
538
- /// Space: O(1)
539
- ///
540
- /// *Runtime and space assumes that `f` runs in O(1) time and space.
541
- public func all<T>(l : List<T>, f : T -> Bool) : Bool {
542
- switch l {
543
- case null { true };
544
- case (?(h, t)) { f(h) and all<T>(t, f) }
545
- }
546
- };
547
-
548
- /// Merge two ordered lists into a single ordered list.
549
- /// This function requires both list to be ordered as specified
550
- /// by the given relation `lessThanOrEqual`.
551
- ///
552
- /// Example:
553
- /// ```motoko include=initialize
554
- ///
555
- /// List.merge<Nat>(
556
- /// ?(1, ?(2, ?(4, null))),
557
- /// ?(2, ?(4, ?(6, null))),
558
- /// func (n1, n2) { n1 <= n2 }
559
- /// ); // => ?(1, ?(2, ?(2, ?(4, ?(4, ?(6, null))))))),
560
- /// ```
561
- ///
562
- /// Runtime: O(size(l1) + size(l2))
563
- ///
564
- /// Space: O(size(l1) + size(l2))
565
- ///
566
- /// *Runtime and space assumes that `lessThanOrEqual` runs in O(1) time and space.
567
- // TODO: replace by merge taking a compare : (T, T) -> Order.Order function?
568
- public func merge<T>(l1 : List<T>, l2 : List<T>, lessThanOrEqual : (T, T) -> Bool) : List<T> {
569
- switch (l1, l2) {
570
- case (null, _) { l2 };
571
- case (_, null) { l1 };
572
- case (?(h1, t1), ?(h2, t2)) {
573
- if (lessThanOrEqual(h1, h2)) {
574
- ?(h1, merge<T>(t1, l2, lessThanOrEqual))
575
- } else {
576
- ?(h2, merge<T>(l1, t2, lessThanOrEqual))
577
- }
578
- }
579
- }
580
- };
581
-
582
- private func compareAux<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {
583
- switch (l1, l2) {
584
- case (null, null) { #equal };
585
- case (null, _) { #less };
586
- case (_, null) { #greater };
587
- case (?(h1, t1), ?(h2, t2)) {
588
- switch (compare(h1, h2)) {
589
- case (#equal) { compareAux<T>(t1, t2, compare) };
590
- case other { other }
591
- }
592
- }
593
- }
594
- };
595
-
596
- /// Compare two lists using lexicographic ordering specified by argument function `compare`.
597
- ///
598
- /// Example:
599
- /// ```motoko include=initialize
600
- /// import Nat "mo:base/Nat";
601
- ///
602
- /// List.compare<Nat>(
603
- /// ?(1, ?(2, null)),
604
- /// ?(3, ?(4, null)),
605
- /// Nat.compare
606
- /// ) // => #less
607
- /// ```
608
- ///
609
- /// Runtime: O(size(l1))
610
- ///
611
- /// Space: O(1)
612
- ///
613
- /// *Runtime and space assumes that argument `compare` runs in O(1) time and space.
614
- public func compare<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {
615
- compareAux<T>(l1, l2, compare);
616
- };
617
-
618
- private func equalAux<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {
619
- switch (l1, l2) {
620
- case (?(h1, t1), ?(h2, t2)) {
621
- equal(h1, h2) and equalAux<T>(t1, t2, equal)
622
- };
623
- case (null, null) { true };
624
- case _ { false };
625
- }
626
- };
627
- /// Compare two lists for equality using the argument function `equal` to determine equality of their elements.
628
- ///
629
- /// Example:
630
- /// ```motoko include=initialize
631
- /// import Nat "mo:base/Nat";
632
- ///
633
- /// List.equal<Nat>(
634
- /// ?(1, ?(2, null)),
635
- /// ?(3, ?(4, null)),
636
- /// Nat.equal
637
- /// ); // => false
638
- /// ```
639
- ///
640
- /// Runtime: O(size(l1))
641
- ///
642
- /// Space: O(1)
643
- ///
644
- /// *Runtime and space assumes that argument `equal` runs in O(1) time and space.
645
- public func equal<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {
646
- equalAux<T>(l1, l2, equal);
647
- };
648
-
649
- /// Generate a list based on a length and a function that maps from
650
- /// a list index to a list element.
651
- ///
652
- /// Example:
653
- /// ```motoko include=initialize
654
- /// List.tabulate<Nat>(
655
- /// 3,
656
- /// func n { n * 2 }
657
- /// ) // => ?(0, ?(2, (?4, null)))
658
- /// ```
659
- ///
660
- /// Runtime: O(n)
661
- ///
662
- /// Space: O(n)
663
- ///
664
- /// *Runtime and space assumes that `f` runs in O(1) time and space.
665
- public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {
666
- var i = 0;
667
- var l : List<T> = null;
668
- while (i < n) {
669
- l := ?(f(i), l);
670
- i += 1
671
- };
672
- reverse(l)
673
- };
674
-
675
- /// Create a list with exactly one element.
676
- ///
677
- /// Example:
678
- /// ```motoko include=initialize
679
- /// List.make<Nat>(
680
- /// 0
681
- /// ) // => ?(0, null)
682
- /// ```
683
- ///
684
- /// Runtime: O(1)
685
- ///
686
- /// Space: O(1)
687
- public func make<T>(x : T) : List<T> = ?(x, null);
688
-
689
- /// Create a list of the given length with the same value in each position.
690
- ///
691
- /// Example:
692
- /// ```motoko include=initialize
693
- /// List.replicate<Nat>(
694
- /// 3,
695
- /// 0
696
- /// ) // => ?(0, ?(0, ?(0, null)))
697
- /// ```
698
- ///
699
- /// Runtime: O(n)
700
- ///
701
- /// Space: O(n)
702
- public func replicate<T>(n : Nat, x : T) : List<T> {
703
- var i = 0;
704
- var l : List<T> = null;
705
- while (i < n) {
706
- l := ?(x, l);
707
- i += 1
708
- };
709
- l
710
- };
711
-
712
- /// Create a list of pairs from a pair of lists.
713
- ///
714
- /// If the given lists have different lengths, then the created list will have a
715
- /// length equal to the length of the smaller list.
716
- ///
717
- /// Example:
718
- /// ```motoko include=initialize
719
- /// List.zip<Nat, Text>(
720
- /// ?(0, ?(1, ?(2, null))),
721
- /// ?("0", ?("1", null)),
722
- /// ) // => ?((0, "0"), ?((1, "1"), null))
723
- /// ```
724
- ///
725
- /// Runtime: O(min(size(xs), size(ys)))
726
- ///
727
- /// Space: O(min(size(xs), size(ys)))
728
- public func zip<T, U>(xs : List<T>, ys : List<U>) : List<(T, U)> = zipWith<T, U, (T, U)>(xs, ys, func(x, y) { (x, y) });
729
-
730
- /// Create a list in which elements are created by applying function `f` to each pair `(x, y)` of elements
731
- /// occuring at the same position in list `xs` and list `ys`.
732
- ///
733
- /// If the given lists have different lengths, then the created list will have a
734
- /// length equal to the length of the smaller list.
735
- ///
736
- /// Example:
737
- /// ```motoko include=initialize
738
- /// import Nat = "mo:base/Nat";
739
- /// import Char = "mo:base/Char";
740
- ///
741
- /// List.zipWith<Nat, Char, Text>(
742
- /// ?(0, ?(1, ?(2, null))),
743
- /// ?('a', ?('b', null)),
744
- /// func (n, c) { Nat.toText(n) # Char.toText(c) }
745
- /// ) // => ?("0a", ?("1b", null))
746
- /// ```
747
- ///
748
- /// Runtime: O(min(size(xs), size(ys)))
749
- ///
750
- /// Space: O(min(size(xs), size(ys)))
751
- ///
752
- /// *Runtime and space assumes that `zip` runs in O(1) time and space.
753
- public func zipWith<T, U, V>(
754
- xs : List<T>,
755
- ys : List<U>,
756
- f : (T, U) -> V
757
- ) : List<V> {
758
- switch (pop<T>(xs)) {
759
- case (null, _) { null };
760
- case (?x, xt) {
761
- switch (pop<U>(ys)) {
762
- case (null, _) { null };
763
- case (?y, yt) {
764
- push<V>(f(x, y), zipWith<T, U, V>(xt, yt, f))
765
- }
766
- }
767
- }
768
- }
769
- };
770
-
771
- /// Split the given list at the given zero-based index.
772
- ///
773
- /// Example:
774
- /// ```motoko include=initialize
775
- /// List.split<Nat>(
776
- /// 2,
777
- /// ?(0, ?(1, ?(2, null)))
778
- /// ) // => (?(0, ?(1, null)), ?(2, null))
779
- /// ```
780
- ///
781
- /// Runtime: O(n)
782
- ///
783
- /// Space: O(n)
784
- ///
785
- /// *Runtime and space assumes that `zip` runs in O(1) time and space.
786
- public func split<T>(n : Nat, xs : List<T>) : (List<T>, List<T>) {
787
- if (n == 0) { (null, xs) } else {
788
- func rec(n : Nat, xs : List<T>) : (List<T>, List<T>) {
789
- switch (pop<T>(xs)) {
790
- case (null, _) { (null, null) };
791
- case (?h, t) {
792
- if (n == 1) { (make<T>(h), t) } else {
793
- let (l, r) = rec(n - 1, t);
794
- (push<T>(h, l), r)
795
- }
796
- }
797
- }
798
- };
799
- rec(n, xs)
800
- }
801
- };
802
-
803
- /// Split the given list into chunks of length `n`.
804
- /// The last chunk will be shorter if the length of the given list
805
- /// does not divide by `n` evenly.
806
- ///
807
- /// Example:
808
- /// ```motoko include=initialize
809
- /// List.chunks<Nat>(
810
- /// 2,
811
- /// ?(0, ?(1, ?(2, ?(3, ?(4, null)))))
812
- /// )
813
- /// /* => ?(?(0, ?(1, null)),
814
- /// ?(?(2, ?(3, null)),
815
- /// ?(?(4, null),
816
- /// null)))
817
- /// */
818
- /// ```
819
- ///
820
- /// Runtime: O(size)
821
- ///
822
- /// Space: O(size)
823
- ///
824
- /// *Runtime and space assumes that `zip` runs in O(1) time and space.
825
- public func chunks<T>(n : Nat, xs : List<T>) : List<List<T>> {
826
- let (l, r) = split<T>(n, xs);
827
- if (isNil<T>(l)) {
828
- null
829
- } else {
830
- push<List<T>>(l, chunks<T>(n, r))
831
- }
832
- };
833
-
834
- /// Convert an array into a list.
835
- ///
836
- /// Example:
837
- /// ```motoko include=initialize
838
- /// List.fromArray<Nat>([ 0, 1, 2, 3, 4])
839
- /// // => ?(0, ?(1, ?(2, ?(3, ?(4, null)))))
840
- /// ```
841
- ///
842
- /// Runtime: O(size)
843
- ///
844
- /// Space: O(size)
845
- public func fromArray<T>(xs : [T]) : List<T> {
846
- Array.foldRight<T, List<T>>(
847
- xs,
848
- null,
849
- func(x : T, ys : List<T>) : List<T> {
850
- push<T>(x, ys)
851
- }
852
- )
853
- };
854
-
855
- /// Convert a mutable array into a list.
856
- ///
857
- /// Example:
858
- /// ```motoko include=initialize
859
- /// List.fromVarArray<Nat>([var 0, 1, 2, 3, 4])
860
- /// // => ?(0, ?(1, ?(2, ?(3, ?(4, null)))))
861
- /// ```
862
- ///
863
- /// Runtime: O(size)
864
- ///
865
- /// Space: O(size)
866
- public func fromVarArray<T>(xs : [var T]) : List<T> = fromArray<T>(Array.freeze<T>(xs));
867
-
868
- /// Create an array from a list.
869
- /// Example:
870
- /// ```motoko include=initialize
871
- /// List.toArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))
872
- /// // => [0, 1, 2, 3, 4]
873
- /// ```
874
- ///
875
- /// Runtime: O(size)
876
- ///
877
- /// Space: O(size)
878
- public func toArray<T>(xs : List<T>) : [T] {
879
- let length = size<T>(xs);
880
- var list = xs;
881
- Array.tabulate<T>(
882
- length,
883
- func(i) {
884
- let popped = pop<T>(list);
885
- list := popped.1;
886
- switch (popped.0) {
887
- case null { loop { assert false } };
888
- case (?x) x
889
- }
890
- }
891
- )
892
- };
893
-
894
- /// Create a mutable array from a list.
895
- /// Example:
896
- /// ```motoko include=initialize
897
- /// List.toVarArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))
898
- /// // => [var 0, 1, 2, 3, 4]
899
- /// ```
900
- ///
901
- /// Runtime: O(size)
902
- ///
903
- /// Space: O(size)
904
- public func toVarArray<T>(xs : List<T>) : [var T] = Array.thaw<T>(toArray<T>(xs));
905
-
906
- /// Create an iterator from a list.
907
- /// Example:
908
- /// ```motoko include=initialize
909
- /// var sum = 0;
910
- /// for (n in List.toIter<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))) {
911
- /// sum += n;
912
- /// };
913
- /// sum
914
- /// // => 10
915
- /// ```
916
- ///
917
- /// Runtime: O(1)
918
- ///
919
- /// Space: O(1)
920
- public func toIter<T>(xs : List<T>) : Iter.Iter<T> {
921
- var state = xs;
922
- object {
923
- public func next() : ?T = switch state {
924
- case (?(hd, tl)) { state := tl; ?hd };
925
- case _ null
926
- }
927
- }
928
- }
929
-
930
- }