@effekt-lang/effekt 0.47.0 → 0.48.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.
- package/bin/effekt +0 -0
- package/libraries/common/array.effekt +53 -0
- package/libraries/common/buffer.effekt +2 -2
- package/libraries/common/bytearray.effekt +55 -0
- package/libraries/common/char.effekt +87 -0
- package/libraries/common/effekt.effekt +3 -0
- package/libraries/common/io/error.effekt +11 -0
- package/libraries/common/io/filesystem.effekt +71 -9
- package/libraries/common/io/network.effekt +97 -65
- package/libraries/common/io.effekt +1 -2
- package/libraries/common/json.effekt +5 -5
- package/libraries/common/list.effekt +154 -18
- package/libraries/common/map.effekt +35 -1
- package/libraries/common/queue.effekt +1 -1
- package/libraries/common/random.effekt +1 -0
- package/libraries/common/ref.effekt +4 -0
- package/libraries/common/seq.effekt +1 -1
- package/libraries/common/set.effekt +24 -1
- package/libraries/common/stream.effekt +2 -360
- package/libraries/common/string.effekt +30 -0
- package/libraries/common/stringbuffer.effekt +1 -0
- package/libraries/llvm/io.c +281 -8
- package/libraries/llvm/main.c +1 -2
- package/libraries/llvm/rts.ll +14 -7
- package/libraries/llvm/types.c +3 -3
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +2 -2
- package/licenses/mit license - mit-license.html +46 -46
- package/licenses/the bsd license - bsd-license.html +48 -48
- package/licenses/the mit license - mit.html +46 -46
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ module list
|
|
|
3
3
|
import effekt
|
|
4
4
|
import option
|
|
5
5
|
import exception
|
|
6
|
+
import stream
|
|
6
7
|
|
|
7
8
|
/// Immutable linked list for finite sequences of elements.
|
|
8
9
|
type List[A] {
|
|
@@ -167,9 +168,52 @@ def foreachIndex[A](list: List[A]){ f: (Int, A) {Control} => Unit }: Unit = {
|
|
|
167
168
|
/// Map a function `f` over elements in a given list.
|
|
168
169
|
///
|
|
169
170
|
/// O(N)
|
|
170
|
-
def map[A, B](l: List[A]) { f: A => B }
|
|
171
|
-
var acc = Nil
|
|
172
|
-
l.foreach { el =>
|
|
171
|
+
def map[A, B](l: List[A]) { f: A => B }: List[B] = {
|
|
172
|
+
var acc: List[B] = Nil()
|
|
173
|
+
l.foreach { el =>
|
|
174
|
+
acc = Cons(f(el), acc)
|
|
175
|
+
}
|
|
176
|
+
acc.reverse
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/// Map a function `f` over elements and their indices in a given list.
|
|
180
|
+
///
|
|
181
|
+
/// O(N)
|
|
182
|
+
def mapWithIndex[A, B](l: List[A]) { f: (Int, A) => B }: List[B] = {
|
|
183
|
+
var acc: List[B] = Nil()
|
|
184
|
+
l.foreachIndex { (i, el) =>
|
|
185
|
+
acc = Cons(f(i, el), acc)
|
|
186
|
+
}
|
|
187
|
+
acc.reverse
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/// Map a function `f` over elements in a given list,
|
|
191
|
+
/// keeping only the elements for which the function returned `true`,
|
|
192
|
+
/// discarding the elements for which the function returned `false`.
|
|
193
|
+
///
|
|
194
|
+
/// O(N)
|
|
195
|
+
def filter[A](l: List[A]) { shouldKeep: A => Bool }: List[A] = {
|
|
196
|
+
var acc: List[A] = Nil()
|
|
197
|
+
l.foreach { a =>
|
|
198
|
+
if (shouldKeep(a)) {
|
|
199
|
+
acc = Cons(a, acc)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
acc.reverse
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/// Map a function `f` over elements and their indices in a given list,
|
|
206
|
+
/// keeping only the elements for which the function returned `true`,
|
|
207
|
+
/// discarding the elements for which the function returned `false`.
|
|
208
|
+
///
|
|
209
|
+
/// O(N)
|
|
210
|
+
def filterWithIndex[A](l: List[A]) { shouldKeep: (Int, A) => Bool }: List[A] = {
|
|
211
|
+
var acc: List[A] = Nil()
|
|
212
|
+
l.foreachIndex { (i, a) =>
|
|
213
|
+
if (shouldKeep(i, a)) {
|
|
214
|
+
acc = Cons(a, acc)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
173
217
|
acc.reverse
|
|
174
218
|
}
|
|
175
219
|
|
|
@@ -178,13 +222,28 @@ def map[A, B](l: List[A]) { f: A => B } : List[B] = {
|
|
|
178
222
|
/// discarding the elements for which the function returned `None()`.
|
|
179
223
|
///
|
|
180
224
|
/// O(N)
|
|
181
|
-
def
|
|
182
|
-
var acc = Nil
|
|
225
|
+
def collectSome[A, B](l: List[A]) { f : A => Option[B] }: List[B] = {
|
|
226
|
+
var acc: List[B] = Nil()
|
|
183
227
|
l.foreach { a =>
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
case
|
|
187
|
-
|
|
228
|
+
f(a) match {
|
|
229
|
+
case None() => ()
|
|
230
|
+
case Some(b) => acc = Cons(b, acc)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
acc.reverse
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/// Map a function `f` over elements and their indices in a given list,
|
|
237
|
+
/// keeping only the elements for which the function returned `Some(...)`,
|
|
238
|
+
/// discarding the elements for which the function returned `None()`.
|
|
239
|
+
///
|
|
240
|
+
/// O(N)
|
|
241
|
+
def collectWithIndex[A, B](l: List[A]) { f: (Int, A) => Option[B] }: List[B] = {
|
|
242
|
+
var acc: List[B] = Nil()
|
|
243
|
+
l.foreachIndex { (i, a) =>
|
|
244
|
+
f(i, a) match {
|
|
245
|
+
case None() => ()
|
|
246
|
+
case Some(b) => acc = Cons(b, acc)
|
|
188
247
|
}
|
|
189
248
|
}
|
|
190
249
|
acc.reverse
|
|
@@ -205,21 +264,55 @@ def flatMap[A, B](l: List[A]) { f : A => List[B] }: List[B] = {
|
|
|
205
264
|
/// Check if predicate is true for all elements of the given list.
|
|
206
265
|
///
|
|
207
266
|
/// O(N)
|
|
208
|
-
def all[A](list: List[A]) { predicate: A => Bool }: Bool =
|
|
267
|
+
def all[A](list: List[A]) { predicate: A => Bool }: Bool =
|
|
209
268
|
list match {
|
|
210
269
|
case Cons(x, xs) => predicate(x) && all(xs) { predicate }
|
|
211
270
|
case Nil() => true
|
|
212
271
|
}
|
|
213
|
-
}
|
|
214
272
|
|
|
215
273
|
/// Check if predicate is true for at least one element of the given list.
|
|
216
274
|
///
|
|
217
275
|
/// O(N)
|
|
218
|
-
def any[A](list: List[A]) { predicate: A => Bool }: Bool =
|
|
276
|
+
def any[A](list: List[A]) { predicate: A => Bool }: Bool =
|
|
219
277
|
list match {
|
|
220
278
|
case Cons(x, xs) => predicate(x) || any(xs) { predicate }
|
|
221
279
|
case Nil() => false
|
|
222
280
|
}
|
|
281
|
+
|
|
282
|
+
/// Check if the list contains the given `element`,
|
|
283
|
+
/// comparing for equality with the given `eq` function.
|
|
284
|
+
///
|
|
285
|
+
/// O(N)
|
|
286
|
+
def contains[A](list: List[A], element: A) { eq: (A, A) => Bool }: Bool =
|
|
287
|
+
list.any { x => x.eq(element) }
|
|
288
|
+
|
|
289
|
+
/// Find the first index of the given `element`,
|
|
290
|
+
/// comparing for equality with the given `eq` function.
|
|
291
|
+
///
|
|
292
|
+
/// O(N)
|
|
293
|
+
def indexOf[A](list: List[A], element: A) { eq: (A, A) => Bool }: Option[Int] = {
|
|
294
|
+
var result = None()
|
|
295
|
+
list.foreachIndex { (i, a) {label} =>
|
|
296
|
+
if (element.eq(a)) {
|
|
297
|
+
result = Some(i)
|
|
298
|
+
label.break()
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
result
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/// Find the last index of the given `element`,
|
|
305
|
+
/// comparing for equality with the given `eq` function.
|
|
306
|
+
///
|
|
307
|
+
/// O(N)
|
|
308
|
+
def lastIndexOf[A](list: List[A], element: A) { eq: (A, A) => Bool }: Option[Int] = {
|
|
309
|
+
var result = None()
|
|
310
|
+
list.foreachIndex { (i, a) {label} =>
|
|
311
|
+
if (element.eq(a)) {
|
|
312
|
+
result = Some(i)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
result
|
|
223
316
|
}
|
|
224
317
|
|
|
225
318
|
/// Count how many elements of a list satisfy the given predicate.
|
|
@@ -297,10 +390,11 @@ def reverse[A](l: List[A]): List[A] = {
|
|
|
297
390
|
/// ```
|
|
298
391
|
///
|
|
299
392
|
/// O(|l|)
|
|
300
|
-
def reverseOnto[A](l: List[A], other: List[A]): List[A] =
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
393
|
+
def reverseOnto[A](l: List[A], other: List[A]): List[A] =
|
|
394
|
+
l match {
|
|
395
|
+
case Nil() => other
|
|
396
|
+
case Cons(a, rest) => rest.reverseOnto(Cons(a, other))
|
|
397
|
+
}
|
|
304
398
|
|
|
305
399
|
/// Concatenate list `l` with list `other`:
|
|
306
400
|
///
|
|
@@ -347,7 +441,7 @@ def join[A](lists: List[List[A]]): List[A] = {
|
|
|
347
441
|
/// ```
|
|
348
442
|
///
|
|
349
443
|
/// O(N)
|
|
350
|
-
def join[A](lists: List[List[A]], between: List[A]): List[A] =
|
|
444
|
+
def join[A](lists: List[List[A]], between: List[A]): List[A] =
|
|
351
445
|
lists match {
|
|
352
446
|
case Nil() => Nil()
|
|
353
447
|
case Cons(firstList, restOfLists) =>
|
|
@@ -355,7 +449,6 @@ def join[A](lists: List[List[A]], between: List[A]): List[A] = {
|
|
|
355
449
|
restOfLists.flatMap { list => between.append(list)}
|
|
356
450
|
)
|
|
357
451
|
}
|
|
358
|
-
}
|
|
359
452
|
|
|
360
453
|
/// Take the first `n` elements of a given list.
|
|
361
454
|
///
|
|
@@ -836,3 +929,46 @@ def println(l: List[Int]): Unit = println(show(l))
|
|
|
836
929
|
def println(l: List[Double]): Unit = println(show(l))
|
|
837
930
|
def println(l: List[Bool]): Unit = println(show(l))
|
|
838
931
|
def println(l: List[String]): Unit = println(show(l))
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
// Streaming
|
|
935
|
+
// ---------
|
|
936
|
+
|
|
937
|
+
/// Turns a `list` into a producer of a push stream
|
|
938
|
+
/// by emitting each contained value left-to-right.
|
|
939
|
+
def each[A](list: List[A]): Unit / emit[A] =
|
|
940
|
+
list match {
|
|
941
|
+
case Nil() => ()
|
|
942
|
+
case Cons(head, tail) =>
|
|
943
|
+
do emit(head)
|
|
944
|
+
each(tail)
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
def feed[T, R](list: List[T]) { reader: () => R / read[T] }: R = {
|
|
948
|
+
var l = list
|
|
949
|
+
try {
|
|
950
|
+
reader()
|
|
951
|
+
} with read[T] {
|
|
952
|
+
resume {
|
|
953
|
+
l match {
|
|
954
|
+
case Nil() => do stop()
|
|
955
|
+
case Cons(value, rest) =>
|
|
956
|
+
l = rest
|
|
957
|
+
return value
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
def collect[A] { stream: () => Unit / emit[A] }: List[A] =
|
|
964
|
+
returning::collect[A, Unit]{stream}.second
|
|
965
|
+
|
|
966
|
+
namespace returning {
|
|
967
|
+
def collect[A, R] { stream: () => R / emit[A] }: (R, List[A]) =
|
|
968
|
+
try {
|
|
969
|
+
(stream(), Nil())
|
|
970
|
+
} with emit[A] { (v) =>
|
|
971
|
+
val (r, vs) = resume(());
|
|
972
|
+
(r, Cons(v, vs))
|
|
973
|
+
}
|
|
974
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module map
|
|
2
2
|
|
|
3
|
+
import stream
|
|
4
|
+
|
|
3
5
|
/// Ordered finite immutable map, backed by balanced binary trees of logarithmic depth.
|
|
4
6
|
record Map[K, V](tree: internal::Tree[K, V], compare: (K, K) => Ordering at {})
|
|
5
7
|
|
|
@@ -989,4 +991,36 @@ namespace internal {
|
|
|
989
991
|
|
|
990
992
|
"[" ++ res ++ "]"
|
|
991
993
|
}
|
|
992
|
-
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
// Streaming
|
|
998
|
+
// ---------
|
|
999
|
+
|
|
1000
|
+
/// Turns a `map` into a producer of a push stream
|
|
1001
|
+
/// of `(key, value)` pairs by emitting each contained *in order*.
|
|
1002
|
+
def each[K, V](map: Map[K, V]): Unit / emit[(K, V)] =
|
|
1003
|
+
map.foreach { (k, v) => do emit((k, v)) }
|
|
1004
|
+
|
|
1005
|
+
/// Turns a `map` into a producer of a push stream
|
|
1006
|
+
/// of its keys by emitting each contained *in order*.
|
|
1007
|
+
def eachKey[K, V](map: Map[K, V]): Unit / emit[K] =
|
|
1008
|
+
map.foreach { (k, _v) => do emit(k) }
|
|
1009
|
+
|
|
1010
|
+
/// Turns a `map` into a producer of a push stream
|
|
1011
|
+
/// of its values by emitting each contained.
|
|
1012
|
+
def eachValue[K, V](map: Map[K, V]): Unit / emit[V] =
|
|
1013
|
+
map.foreach { (_k, v) => do emit(v) }
|
|
1014
|
+
|
|
1015
|
+
def collect[K, V](compare: (K, K) => Ordering at {}) { stream: () => Unit / emit[(K, V)] }: Map[K, V] =
|
|
1016
|
+
returning::collect[K, V, Unit](compare){stream}.second
|
|
1017
|
+
|
|
1018
|
+
namespace returning {
|
|
1019
|
+
def collect[K, V, R](compare: (K, K) => Ordering at {}) { stream: () => R / emit[(K, V)] }: (R, Map[K, V]) =
|
|
1020
|
+
try {
|
|
1021
|
+
(stream(), empty(compare))
|
|
1022
|
+
} with emit[(K, V)] { case (k, v) =>
|
|
1023
|
+
val (r, map) = resume(());
|
|
1024
|
+
(r, map.put(k, v))
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
@@ -104,3 +104,7 @@ extern def set[T](ref: Ref[T], value: T) at global: Unit =
|
|
|
104
104
|
ret %Pos zeroinitializer
|
|
105
105
|
"""
|
|
106
106
|
vm "ref::set[T](Ref[T], T)"
|
|
107
|
+
|
|
108
|
+
/// Modifies the inner contents of the `ref` with a function `f`
|
|
109
|
+
def map[T](ref: Ref[T]) { f: T => T }: Unit =
|
|
110
|
+
ref.set(f(ref.get))
|
|
@@ -875,7 +875,7 @@ def map[A, B](seq: Seq[A]) { f: (A) {Control} => B }: Seq[B] = {
|
|
|
875
875
|
|
|
876
876
|
// def iterate[A, R](seq: Seq[A]) { prog: {Iterator[A]} => R }: R = {
|
|
877
877
|
|
|
878
|
-
// var k: Unit => Unit at {} =
|
|
878
|
+
// var k: Unit => Unit at {} = box { () => () }
|
|
879
879
|
// var v: Option[A] = None()
|
|
880
880
|
|
|
881
881
|
// try { seq.each { el => do yield(el) } } with Generator[A] {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module set
|
|
2
2
|
|
|
3
3
|
import map
|
|
4
|
+
import stream
|
|
4
5
|
|
|
5
6
|
/// Ordered finite immutable set, backed by balanced binary trees of logarithmic depth.
|
|
6
7
|
record Set[A](tree: internal::Tree[A, Unit], compare: (A, A) => Ordering at {})
|
|
@@ -231,4 +232,26 @@ def intersection[A](s1: Set[A], s2: Set[A], compare: (A, A) => Ordering at {}):
|
|
|
231
232
|
///
|
|
232
233
|
/// O(???)
|
|
233
234
|
def intersection[A](s1: Set[A], s2: Set[A]): Set[A] =
|
|
234
|
-
s1.intersection(s2, s1.compare)
|
|
235
|
+
s1.intersection(s2, s1.compare)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
// Streaming
|
|
239
|
+
// ---------
|
|
240
|
+
|
|
241
|
+
/// Turns a `set` into a producer of a push stream
|
|
242
|
+
/// by emitting each contained *in order*.
|
|
243
|
+
def each[A](set: Set[A]): Unit / emit[A] =
|
|
244
|
+
set.foreach { x => do emit(x) }
|
|
245
|
+
|
|
246
|
+
def collect[A](compare: (A, A) => Ordering at {}) { stream: () => Unit / emit[A] }: Set[A] =
|
|
247
|
+
returning::collect[A, Unit](compare){stream}.second
|
|
248
|
+
|
|
249
|
+
namespace returning {
|
|
250
|
+
def collect[A, R](compare: (A, A) => Ordering at {}) { stream: () => R / emit[A] }: (R, Set[A]) =
|
|
251
|
+
try {
|
|
252
|
+
(stream(), empty(compare))
|
|
253
|
+
} with emit[A] { (v) =>
|
|
254
|
+
val (r, set) = resume(());
|
|
255
|
+
(r, set.insert(v))
|
|
256
|
+
}
|
|
257
|
+
}
|