ic-mops 0.8.3 → 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 (100) 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/mops.js +1 -1
  99. package/network.txt +1 -0
  100. package/package.json +2 -2
@@ -0,0 +1,220 @@
1
+ /// Iterators
2
+
3
+ import Array "Array";
4
+ import Buffer "Buffer";
5
+ import List "List";
6
+ import Order "Order";
7
+
8
+ module {
9
+
10
+ /// An iterator that produces values of type `T`. Calling `next` returns
11
+ /// `null` when iteration is finished.
12
+ ///
13
+ /// Iterators are inherently stateful. Calling `next` "consumes" a value from
14
+ /// the Iterator that cannot be put back, so keep that in mind when sharing
15
+ /// iterators between consumers.
16
+ ///
17
+ /// An iterater `i` can be iterated over using
18
+ /// ```
19
+ /// for (x in i) {
20
+ /// …do something with x…
21
+ /// }
22
+ /// ```
23
+ public type Iter<T> = { next : () -> ?T };
24
+
25
+ /// Creates an iterator that produces all `Nat`s from `x` to `y` including
26
+ /// both of the bounds.
27
+ /// ```motoko
28
+ /// import Iter "mo:base/Iter";
29
+ /// let iter = Iter.range(1, 3);
30
+ /// assert(?1 == iter.next());
31
+ /// assert(?2 == iter.next());
32
+ /// assert(?3 == iter.next());
33
+ /// assert(null == iter.next());
34
+ /// ```
35
+ public class range(x : Nat, y : Int) {
36
+ var i = x;
37
+ public func next() : ?Nat { if (i > y) { null } else {let j = i; i += 1; ?j} };
38
+ };
39
+
40
+ /// Like `range` but produces the values in the opposite
41
+ /// order.
42
+ public class revRange(x : Int, y : Int) {
43
+ var i = x;
44
+ public func next() : ?Int { if (i < y) { null } else {let j = i; i -= 1; ?j} };
45
+ };
46
+
47
+ /// Calls a function `f` on every value produced by an iterator and discards
48
+ /// the results. If you're looking to keep these results use `map` instead.
49
+ ///
50
+ /// ```motoko
51
+ /// import Iter "mo:base/Iter";
52
+ /// var sum = 0;
53
+ /// Iter.iterate<Nat>(Iter.range(1, 3), func(x, _index) {
54
+ /// sum += x;
55
+ /// });
56
+ /// assert(6 == sum)
57
+ /// ```
58
+ public func iterate<A>(
59
+ xs : Iter<A>,
60
+ f : (A, Nat) -> ()
61
+ ) {
62
+ var i = 0;
63
+ label l loop {
64
+ switch (xs.next()) {
65
+ case (?next) {
66
+ f(next, i);
67
+ };
68
+ case (null) {
69
+ break l;
70
+ };
71
+ };
72
+ i += 1;
73
+ continue l;
74
+ };
75
+ };
76
+
77
+ /// Consumes an iterator and counts how many elements were produced
78
+ /// (discarding them in the process).
79
+ public func size<A>(xs : Iter<A>) : Nat {
80
+ var len = 0;
81
+ iterate<A>(xs, func (x, i) { len += 1; });
82
+ len;
83
+ };
84
+
85
+ /// Takes a function and an iterator and returns a new iterator that lazily applies
86
+ /// the function to every element produced by the argument iterator.
87
+ /// ```motoko
88
+ /// import Iter "mo:base/Iter";
89
+ /// let iter = Iter.range(1, 3);
90
+ /// let mappedIter = Iter.map(iter, func (x : Nat) : Nat { x * 2 });
91
+ /// assert(?2 == mappedIter.next());
92
+ /// assert(?4 == mappedIter.next());
93
+ /// assert(?6 == mappedIter.next());
94
+ /// assert(null == mappedIter.next());
95
+ /// ```
96
+ public func map<A, B>(xs : Iter<A>, f : A -> B) : Iter<B> = object {
97
+ public func next() : ?B {
98
+ switch (xs.next()) {
99
+ case (?next) {
100
+ ?f(next);
101
+ };
102
+ case (null) {
103
+ null;
104
+ };
105
+ };
106
+ };
107
+ };
108
+
109
+ /// Takes a function and an iterator and returns a new iterator that produces
110
+ /// elements from the original iterator if and only if the predicate is true.
111
+ /// ```motoko
112
+ /// import Iter "o:base/Iter";
113
+ /// let iter = Iter.range(1, 3);
114
+ /// let mappedIter = Iter.filter(iter, func (x : Nat) : Bool { x % 2 == 1 });
115
+ /// assert(?1 == mappedIter.next());
116
+ /// assert(?3 == mappedIter.next());
117
+ /// assert(null == mappedIter.next());
118
+ /// ```
119
+ public func filter<A>(xs : Iter<A>, f : A -> Bool) : Iter<A> = object {
120
+ public func next() : ?A {
121
+ loop {
122
+ switch (xs.next()) {
123
+ case (null) {
124
+ return null;
125
+ };
126
+ case (?x) {
127
+ if (f(x)) {
128
+ return ?x;
129
+ };
130
+ };
131
+ };
132
+ };
133
+ null;
134
+ };
135
+ };
136
+
137
+ /// Creates an iterator that produces an infinite sequence of `x`.
138
+ /// ```motoko
139
+ /// import Iter "mo:base/Iter";
140
+ /// let iter = Iter.make(10);
141
+ /// assert(?10 == iter.next());
142
+ /// assert(?10 == iter.next());
143
+ /// assert(?10 == iter.next());
144
+ /// // ...
145
+ /// ```
146
+ public func make<A>(x : A) : Iter<A> = object {
147
+ public func next() : ?A {
148
+ ?x;
149
+ };
150
+ };
151
+
152
+ /// Creates an iterator that produces the elements of an Array in ascending index order.
153
+ /// ```motoko
154
+ /// import Iter "mo:base/Iter";
155
+ /// let iter = Iter.fromArray([1, 2, 3]);
156
+ /// assert(?1 == iter.next());
157
+ /// assert(?2 == iter.next());
158
+ /// assert(?3 == iter.next());
159
+ /// assert(null == iter.next());
160
+ /// ```
161
+ public func fromArray<A>(xs : [A]) : Iter<A> {
162
+ var ix : Nat = 0;
163
+ let size = xs.size();
164
+ object {
165
+ public func next() : ?A {
166
+ if (ix >= size) {
167
+ return null
168
+ } else {
169
+ let res = ?(xs[ix]);
170
+ ix += 1;
171
+ return res
172
+ }
173
+ }
174
+ }
175
+ };
176
+
177
+ /// Like `fromArray` but for Arrays with mutable elements. Captures
178
+ /// the elements of the Array at the time the iterator is created, so
179
+ /// further modifications won't be reflected in the iterator.
180
+ public func fromArrayMut<A>(xs : [var A]) : Iter<A> {
181
+ fromArray<A>(Array.freeze<A>(xs));
182
+ };
183
+
184
+ /// Like `fromArray` but for Lists.
185
+ public let fromList = List.toIter;
186
+
187
+ /// Consumes an iterator and collects its produced elements in an Array.
188
+ /// ```motoko
189
+ /// import Iter "mo:base/Iter";
190
+ /// let iter = Iter.range(1, 3);
191
+ /// assert([1, 2, 3] == Iter.toArray(iter));
192
+ /// ```
193
+ public func toArray<A>(xs : Iter<A>) : [A] {
194
+ let buffer = Buffer.Buffer<A>(8);
195
+ iterate(xs, func(x : A, ix : Nat) { buffer.add(x) });
196
+ return Buffer.toArray(buffer)
197
+ };
198
+
199
+ /// Like `toArray` but for Arrays with mutable elements.
200
+ public func toArrayMut<A>(xs : Iter<A>) : [var A] {
201
+ Array.thaw<A>(toArray<A>(xs));
202
+ };
203
+
204
+ /// Like `toArray` but for Lists.
205
+ public func toList<A>(xs : Iter<A>) : List.List<A> {
206
+ var result = List.nil<A>();
207
+ iterate<A>(xs, func (x, _i) {
208
+ result := List.push<A>(x, result);
209
+ });
210
+ List.reverse<A>(result);
211
+ };
212
+
213
+ /// Sorted iterator. Will iterate over *all* elements to sort them, necessarily.
214
+ public func sort<A>(xs : Iter<A>, compare : (A, A) -> Order.Order) : Iter<A> {
215
+ let a = toArrayMut<A>(xs);
216
+ Array.sortInPlace<A>(a, compare);
217
+ fromArrayMut<A>(a)
218
+ };
219
+
220
+ };
@@ -0,0 +1,7 @@
1
+ /// The Iterator type
2
+
3
+ // Just here to break cyclic module definitions
4
+
5
+ module {
6
+ public type Iter<T> = { next : () -> ?T };
7
+ }
@@ -0,0 +1,433 @@
1
+ /// Purely-functional, singly-linked lists.
2
+
3
+ import Array "Array";
4
+ import Iter "IterType";
5
+ import Option "Option";
6
+ import Order "Order";
7
+ import Result "Result";
8
+
9
+ module {
10
+
11
+ // A singly-linked list consists of zero or more _cons cells_, wherein
12
+ // each cell contains a single list element (the cell's _head_), and a pointer to the
13
+ // remainder of the list (the cell's _tail_).
14
+ public type List<T> = ?(T, List<T>);
15
+
16
+ /// Create an empty list.
17
+ public func nil<T>() : List<T> = null;
18
+
19
+ /// Check whether a list is empty and return true if the list is empty.
20
+ public func isNil<T>(l : List<T>) : Bool {
21
+ switch l {
22
+ case null { true };
23
+ case _ { false };
24
+ }
25
+ };
26
+
27
+ /// Construct a list by pre-pending a value.
28
+ /// This function is similar to a `list.cons(item)` function.
29
+ public func push<T>(x : T, l : List<T>) : List<T> = ?(x, l);
30
+
31
+ /// Return the last element of the list, if present.
32
+ public func last<T>(l : List<T>) : ?T {
33
+ switch l {
34
+ case null { null };
35
+ case (?(x, null)) { ?x };
36
+ case (?(_, t)) { last<T>(t) };
37
+ }
38
+ };
39
+
40
+ /// Treat the list as a stack.
41
+ /// This function combines the `head` and (non-failing) `tail` operations into one operation.
42
+ public func pop<T>(l : List<T>) : (?T, List<T>) {
43
+ switch l {
44
+ case null { (null, null) };
45
+ case (?(h, t)) { (?h, t) };
46
+ }
47
+ };
48
+
49
+ /// Return the length of the list.
50
+ public func size<T>(l : List<T>) : Nat {
51
+ func rec(l : List<T>, n : Nat) : Nat {
52
+ switch l {
53
+ case null { n };
54
+ case (?(_, t)) { rec(t, n + 1) };
55
+ }
56
+ };
57
+ rec(l,0)
58
+ };
59
+ /// Access any item in a list, zero-based.
60
+ ///
61
+ /// NOTE: Indexing into a list is a linear operation, and usually an
62
+ /// indication that a list might not be the best data structure
63
+ /// to use.
64
+ public func get<T>(l : List<T>, n : Nat) : ?T {
65
+ switch (n, l) {
66
+ case (_, null) { null };
67
+ case (0, (?(h, t))) { ?h };
68
+ case (_, (?(_, t))) { get<T>(t, n - 1) };
69
+ }
70
+ };
71
+
72
+ /// Reverses the list
73
+ public func reverse<T>(l : List<T>) : List<T> {
74
+ func rec(l : List<T>, r : List<T>) : List<T> {
75
+ switch l {
76
+ case null { r };
77
+ case (?(h, t)) { rec(t, ?(h, r)) };
78
+ }
79
+ };
80
+ rec(l, null)
81
+ };
82
+
83
+ /// Call the given function with each list element in turn.
84
+ ///
85
+ /// This function is equivalent to the `app` function in Standard ML Basis,
86
+ /// and the `iter` function in OCaml.
87
+ public func iterate<T>(l : List<T>, f : T -> ()) {
88
+ switch l {
89
+ case null { () };
90
+ case (?(h, t)) { f(h); iterate<T>(t, f) };
91
+ }
92
+ };
93
+
94
+ /// Call the given function on each list element and collect the results
95
+ /// in a new list.
96
+ public func map<T, S>(l : List<T>, f : T -> S) : List<S> {
97
+ switch l {
98
+ case null { null };
99
+ case (?(h, t)) { ?(f(h), map<T, S>(t, f)) };
100
+ }
101
+ };
102
+
103
+ /// Create a new list with only those elements of the original list for which
104
+ /// the given function (often called the _predicate_) returns true.
105
+ public func filter<T>(l : List<T>, f : T -> Bool) : List<T> {
106
+ switch l {
107
+ case null { null };
108
+ case (?(h,t)) {
109
+ if (f(h)) {
110
+ ?(h,filter<T>(t, f))
111
+ } else {
112
+ filter<T>(t, f)
113
+ }
114
+ };
115
+ };
116
+ };
117
+
118
+ /// Create two new lists from the results of a given function (`f`).
119
+ /// The first list only includes the elements for which the given
120
+ /// function `f` returns true and the second list only includes
121
+ /// the elements for which the function returns false.
122
+ public func partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>) {
123
+ switch l {
124
+ case null { (null, null) };
125
+ case (?(h, t)) {
126
+ if (f(h)) { // call f in-order
127
+ let (l, r) = partition<T>(t, f);
128
+ (?(h, l), r)
129
+ } else {
130
+ let (l, r) = partition<T>(t, f);
131
+ (l, ?(h, r))
132
+ }
133
+ };
134
+ };
135
+ };
136
+
137
+ /// Call the given function on each list element, and collect the non-null results
138
+ /// in a new list.
139
+ public func mapFilter<T,S>(l : List<T>, f : T -> ?S) : List<S> {
140
+ switch l {
141
+ case null { null };
142
+ case (?(h,t)) {
143
+ switch (f(h)) {
144
+ case null { mapFilter<T,S>(t, f) };
145
+ case (?h_){ ?(h_,mapFilter<T,S>(t, f)) };
146
+ }
147
+ };
148
+ };
149
+ };
150
+
151
+ /// Maps a Result-returning function over a List and returns either
152
+ /// the first error or a list of successful values.
153
+ public func mapResult<A, R, E>(xs : List<A>, f : A -> Result.Result<R, E>) : Result.Result<List<R>, E> {
154
+ func go(xs : List<A>, acc : List<R>) : Result.Result<List<R>, E> {
155
+ switch xs {
156
+ case null { #ok(acc) };
157
+ case (?(head, tail)) {
158
+ switch (f(head)) {
159
+ case (#err(err)) { #err(err) };
160
+ case (#ok(ok)) { go(tail, ?(ok, acc)) };
161
+ };
162
+ };
163
+ }
164
+ };
165
+ Result.mapOk(go(xs, null), func (xs : List<R>) : List<R> = reverse(xs))
166
+ };
167
+
168
+ /// Append the elements from the reverse of one list to another list.
169
+ func revAppend<T>(l : List<T>, m : List<T>) : List<T> {
170
+ switch l {
171
+ case null { m };
172
+ case (?(h, t)) { revAppend(t, ?(h, m)) };
173
+ }
174
+ };
175
+
176
+ /// Append the elements from one list to another list.
177
+ public func append<T>(l : List<T>, m : List<T>) : List<T> {
178
+ revAppend(reverse(l), m);
179
+ };
180
+
181
+ /// Concatenate a list of lists.
182
+ ///
183
+ /// In some languages, this operation is also known as a `list join`.
184
+ public func flatten<T>(l : List<List<T>>) : List<T> {
185
+ foldLeft<List<T>, List<T>>(l, null, func(a, b) { append<T>(a,b) });
186
+ };
187
+
188
+ /// Returns the first `n` elements of the given list.
189
+ /// If the given list has fewer than `n` elements, this function returns
190
+ /// a copy of the full input list.
191
+ public func take<T>(l : List<T>, n:Nat) : List<T> {
192
+ switch (l, n) {
193
+ case (_, 0) { null };
194
+ case (null, _) { null };
195
+ case (?(h, t), m) {?(h, take<T>(t, m - 1))};
196
+ }
197
+ };
198
+
199
+ /// Drop the first `n` elements from the given list.
200
+ public func drop<T>(l : List<T>, n:Nat) : List<T> {
201
+ switch (l, n) {
202
+ case (l_, 0) { l_ };
203
+ case (null, _) { null };
204
+ case ((?(h, t)), m) { drop<T>(t, m - 1) };
205
+ }
206
+ };
207
+
208
+ /// Fold the list left-to-right using the given function (`f`).
209
+ public func foldLeft<T, S>(l : List<T>, a : S, f : (S, T) -> S) : S {
210
+ switch l {
211
+ case null { a };
212
+ case (?(h, t)) { foldLeft(t, f(a, h), f) };
213
+ };
214
+ };
215
+
216
+ /// Fold the list right-to-left using the given function (`f`).
217
+ public func foldRight<T, S>(l : List<T>, a : S, f : (T, S) -> S) : S {
218
+ switch l {
219
+ case null { a };
220
+ case (?(h, t)) { f(h, foldRight<T,S>(t, a, f)) };
221
+ };
222
+ };
223
+
224
+ /// Return the first element for which the given predicate `f` is true,
225
+ /// if such an element exists.
226
+ public func find<T>(l: List<T>, f:T -> Bool) : ?T {
227
+ switch l {
228
+ case null { null };
229
+ case (?(h, t)) { if (f(h)) { ?h } else { find<T>(t, f) } };
230
+ };
231
+ };
232
+
233
+ /// Return true if there exists a list element for which
234
+ /// the given predicate `f` is true.
235
+ public func some<T>(l : List<T>, f : T -> Bool) : Bool {
236
+ switch l {
237
+ case null { false };
238
+ case (?(h, t)) { f(h) or some<T>(t, f)};
239
+ };
240
+ };
241
+
242
+ /// Return true if the given predicate `f` is true for all list
243
+ /// elements.
244
+ public func all<T>(l : List<T>, f : T -> Bool) : Bool {
245
+ switch l {
246
+ case null { true };
247
+ case (?(h, t)) { f(h) and all<T>(t, f) };
248
+ }
249
+ };
250
+
251
+ /// Merge two ordered lists into a single ordered list.
252
+ /// This function requires both list to be ordered as specified
253
+ /// by the given relation `lte`.
254
+ public func merge<T>(l1 : List<T>, l2 : List<T>, lte : (T, T) -> Bool) : List<T> {
255
+ switch (l1, l2) {
256
+ case (null, _) { l2 };
257
+ case (_, null) { l1 };
258
+ case (?(h1, t1), ?(h2, t2)) {
259
+ if (lte(h1, h2)) {
260
+ ?(h1, merge<T>(t1, l2, lte))
261
+ } else {
262
+ ?(h2, merge<T>(l1, t2, lte))
263
+ }
264
+ };
265
+ }
266
+ };
267
+
268
+ /// Compare two lists using lexicographic ordering specified by the given relation `lte`.
269
+ public func compare<T>(l1 : List<T>, l2 : List<T>, compElm: (T, T) -> Order.Order) : Order.Order {
270
+ switch (l1, l2) {
271
+ case (null, null) { #equal };
272
+ case (null, _) { #less };
273
+ case (_, null) { #greater };
274
+ case (?(h1, t1), ?(h2, t2)) {
275
+ let hOrder = compElm(h1, h2);
276
+ if (Order.isEqual(hOrder)) {
277
+ compare<T>(t1, t2, compElm)
278
+ } else {
279
+ hOrder
280
+ }
281
+ };
282
+ };
283
+ };
284
+
285
+ /// Compare two lists for equality as specified by the given relation `eq` on the elements.
286
+ ///
287
+ /// The function `isEq(l1, l2)` is equivalent to `lessThanEq(l1, l2) && lessThanEq(l2, l1)`,
288
+ /// but the former is more efficient.
289
+ public func equal<T>(l1 : List<T>, l2 : List<T>, eq :(T, T) -> Bool) : Bool {
290
+ switch (l1, l2) {
291
+ case (null, null) { true };
292
+ case (null, _) { false };
293
+ case (_, null) { false };
294
+ case (?(h1, t1), ?(h2, t2)) { eq(h1, h2) and equal<T>(t1, t2, eq) };
295
+ }
296
+ };
297
+
298
+ /// Generate a list based on a length and a function that maps from
299
+ /// a list index to a list element.
300
+ public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {
301
+ var i = 0;
302
+ var l : List<T> = null;
303
+ while (i < n) {
304
+ l := ?(f(i), l);
305
+ i += 1;
306
+ };
307
+ reverse(l);
308
+ };
309
+
310
+ /// Create a list with exactly one element.
311
+ public func make<X>(x : X) : List<X> = ?(x, null);
312
+
313
+ /// Create a list of the given length with the same value in each position.
314
+ public func replicate<X>(n : Nat, x : X) : List<X> {
315
+ var i = 0;
316
+ var l : List<X> = null;
317
+ while (i < n) {
318
+ l := ?(x, l);
319
+ i += 1;
320
+ };
321
+ l;
322
+ };
323
+
324
+ /// Create a list of pairs from a pair of lists.
325
+ ///
326
+ /// If the given lists have different lengths, then the created list will have a
327
+ /// length equal to the length of the smaller list.
328
+ public func zip<X, Y>(xs : List<X>, ys : List<Y>) : List<(X, Y)> =
329
+ zipWith<X, Y, (X, Y)>(xs, ys, func (x, y) { (x, y) });
330
+
331
+ /// Create a list in which elements are calculated from the function `f` and
332
+ /// include elements occuring at the same position in the given lists.
333
+ ///
334
+ /// If the given lists have different lengths, then the created list will have a
335
+ /// length equal to the length of the smaller list.
336
+ public func zipWith<X, Y, Z>(
337
+ xs : List<X>,
338
+ ys : List<Y>,
339
+ f : (X, Y) -> Z
340
+ ) : List<Z> {
341
+ switch (pop<X>(xs)) {
342
+ case (null, _) { null };
343
+ case (?x, xt) {
344
+ switch (pop<Y>(ys)) {
345
+ case (null, _) { null };
346
+ case (?y, yt) {
347
+ push<Z>(f(x, y), zipWith<X, Y, Z>(xt, yt, f))
348
+ }
349
+ }
350
+ }
351
+ }
352
+ };
353
+
354
+ /// Split the given list at the given zero-based index.
355
+ public func split<X>(n : Nat, xs : List<X>) : (List<X>, List<X>) {
356
+ if (n == 0) {
357
+ (null, xs)
358
+ } else {
359
+ func rec(n : Nat, xs : List<X>) : (List<X>, List<X>) {
360
+ switch (pop<X>(xs)) {
361
+ case (null, _) {
362
+ (null, null)
363
+ };
364
+ case (?h, t) {
365
+ if (n == 1) {
366
+ (make<X>(h), t)
367
+ } else {
368
+ let (l, r) = rec(n - 1, t);
369
+ (push<X>(h, l), r)
370
+ }
371
+ }
372
+ }
373
+ };
374
+ rec(n, xs)
375
+ }
376
+ };
377
+
378
+ /// Split the given list into chunks of length `n`.
379
+ /// The last chunk will be shorter if the length of the given list
380
+ /// does not divide by `n` evenly.
381
+ public func chunks<X>(n : Nat, xs : List<X>) : List<List<X>> {
382
+ let (l, r) = split<X>(n, xs);
383
+ if (isNil<X>(l)) {
384
+ null
385
+ } else {
386
+ push<List<X>>(l, chunks<X>(n, r))
387
+ }
388
+ };
389
+
390
+ /// Convert an array into a list.
391
+ public func fromArray<A>(xs : [A]) : List<A> {
392
+ Array.foldRight<A, List<A>>(
393
+ xs, nil<A>(),
394
+ func (x : A, ys : List<A>) : List<A> {
395
+ push<A>(x, ys);
396
+ });
397
+ };
398
+
399
+ /// Convert a mutable array into a list.
400
+ public func fromVarArray<A>(xs : [var A]) : List<A> =
401
+ fromArray<A>(Array.freeze<A>(xs));
402
+
403
+ /// Create an array from a list.
404
+ public func toArray<A>(xs : List<A>) : [A] {
405
+ let length = size<A>(xs);
406
+ var list = xs;
407
+ Array.tabulate<A>(length, func (i) {
408
+ let popped = pop<A>(list);
409
+ list := popped.1;
410
+ switch (popped.0) {
411
+ case null { loop { assert false } };
412
+ case (?x) x;
413
+ }
414
+ });
415
+ };
416
+
417
+ /// Create a mutable array from a list.
418
+ public func toVarArray<A>(xs : List<A>) : [var A] =
419
+ Array.thaw<A>(toArray<A>(xs));
420
+
421
+ /// Create an iterator from a list.
422
+ public func toIter<A>(xs : List<A>) : Iter.Iter<A> {
423
+ var state = xs;
424
+ object {
425
+ public func next() : ?A =
426
+ switch state {
427
+ case (?(hd, tl)) { state := tl; ?hd };
428
+ case _ null
429
+ }
430
+ }
431
+ }
432
+
433
+ }