@effekt-lang/effekt 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/bin/effekt +0 -0
  4. package/bin/effekt.sh +2 -0
  5. package/libraries/chez/THIRD-PARTY.txt +11 -0
  6. package/libraries/chez/callcc/datatype.ss +188 -0
  7. package/libraries/chez/callcc/effekt.ss +31 -0
  8. package/libraries/chez/callcc/seq.ss +44 -0
  9. package/libraries/chez/callcc/seq0.ss +69 -0
  10. package/libraries/chez/callcc/tail.ss +76 -0
  11. package/libraries/chez/callcc/tail0.ss +89 -0
  12. package/libraries/chez/common/effekt_primitives.ss +105 -0
  13. package/libraries/chez/common/immutable/cslist.effekt +37 -0
  14. package/libraries/chez/common/mutable/dict.effekt +28 -0
  15. package/libraries/chez/common/text/pregexp.scm +772 -0
  16. package/libraries/chez/common/text/regex.effekt +31 -0
  17. package/libraries/chez/lift/effekt.ss +118 -0
  18. package/libraries/chez/monadic/effekt.ss +84 -0
  19. package/libraries/chez/monadic/seq0.ss +76 -0
  20. package/libraries/common/args.effekt +95 -0
  21. package/libraries/common/array.effekt +225 -0
  22. package/libraries/common/bench.effekt +60 -0
  23. package/libraries/common/buffer.effekt +123 -0
  24. package/libraries/common/bytes.effekt +125 -0
  25. package/libraries/common/dequeue.effekt +92 -0
  26. package/libraries/common/effekt.effekt +764 -0
  27. package/libraries/common/exception.effekt +122 -0
  28. package/libraries/common/io/console.effekt +66 -0
  29. package/libraries/common/io/error.effekt +365 -0
  30. package/libraries/common/io/files.effekt +282 -0
  31. package/libraries/common/io/network.effekt +105 -0
  32. package/libraries/common/io/time.effekt +15 -0
  33. package/libraries/common/io.effekt +158 -0
  34. package/libraries/common/list.effekt +687 -0
  35. package/libraries/common/option.effekt +72 -0
  36. package/libraries/common/process.effekt +10 -0
  37. package/libraries/common/queue.effekt +140 -0
  38. package/libraries/common/ref.effekt +63 -0
  39. package/libraries/common/result.effekt +45 -0
  40. package/libraries/common/seq.effekt +914 -0
  41. package/libraries/common/string.effekt +395 -0
  42. package/libraries/common/test.effekt +98 -0
  43. package/libraries/js/effekt_builtins.js +57 -0
  44. package/libraries/js/effekt_runtime.js +385 -0
  45. package/libraries/js/io.js +143 -0
  46. package/libraries/js/mutable/map.effekt +31 -0
  47. package/libraries/js/text/regex.effekt +33 -0
  48. package/libraries/js/unsafe/cont.effekt +11 -0
  49. package/libraries/js/web/dom.effekt +45 -0
  50. package/libraries/llvm/array.c +53 -0
  51. package/libraries/llvm/buffer.c +286 -0
  52. package/libraries/llvm/forward-declare-c.ll +43 -0
  53. package/libraries/llvm/hole.c +11 -0
  54. package/libraries/llvm/io.c +566 -0
  55. package/libraries/llvm/io.ll +19 -0
  56. package/libraries/llvm/main.c +41 -0
  57. package/libraries/llvm/ref.c +45 -0
  58. package/libraries/llvm/rts.ll +761 -0
  59. package/libraries/llvm/sanity.c +16 -0
  60. package/libraries/llvm/types.c +43 -0
  61. package/libraries/ml/effekt.sml +65 -0
  62. package/libraries/ml/internal/mllist.effekt +9 -0
  63. package/libraries/ml/internal/mloption.effekt +18 -0
  64. package/libraries/ml/random.effekt +85 -0
  65. package/libraries/ml/text/regex.effekt +102 -0
  66. package/licenses/THIRD-PARTY.txt +21 -0
  67. package/licenses/apache-2.0 - license-2.0.txt +202 -0
  68. package/licenses/eclipse public license, version 2.0 - epl-2.0.html +61 -0
  69. package/licenses/kiama-license.txt +373 -0
  70. package/licenses/kiama-readme.txt +186 -0
  71. package/licenses/mit license - mit-license.html +1239 -0
  72. package/licenses/the apache software license, version 2.0 - license-2.0.txt +202 -0
  73. package/licenses/the bsd license - bsd-license.html +1237 -0
  74. package/licenses/the mit license - mit.html +1239 -0
  75. package/package.json +26 -18
@@ -0,0 +1,914 @@
1
+ module seq
2
+
3
+ /**
4
+ * This file implements the [[Seq]] type as a general purpose functional sequence.
5
+ *
6
+ * Implemented as a 2-3 finger tree, it supports
7
+ * - prepend and append in amortized O(1),
8
+ * - concat(m, n) in O(log(min(m, n)))
9
+ * - first and last in amortized O(1)
10
+ * - size in amortized O(1)
11
+ *
12
+ * More information on finger trees:
13
+ * https://www.staff.city.ac.uk/~ross/papers/FingerTree.pdf
14
+ */
15
+
16
+ /**
17
+ * Sequences of elements
18
+ *
19
+ * They are represented as 2-3 finger trees.
20
+ */
21
+ type Seq[A] {
22
+ Empty()
23
+ Single(value: A)
24
+ Deep(size: Int, prefix: Digit[A], middle: Tree[A], suffix: Digit[A])
25
+ }
26
+
27
+ /**
28
+ * Result of splitting a sequence at the front or back.
29
+ */
30
+ type View[A] {
31
+ IsEmpty()
32
+ View(element: A, remainder: Seq[A])
33
+ }
34
+
35
+ /**
36
+ * Exception[NoSuchElement] is raised when accessing non-existing elements
37
+ * or splitting empty collections.
38
+ */
39
+ record NoSuchElement()
40
+
41
+
42
+ record IndexOutOfBounds()
43
+
44
+
45
+
46
+ // Implementation
47
+ // ==============
48
+ // Internal implementation note:
49
+ // we use the following abbreviations:
50
+ // - s: suffix
51
+ // - p: prefix
52
+ // - v: value
53
+ // - n: node
54
+ // - m: middle (spine)
55
+ // - a,b,c,d: elements of a digit in this order
56
+ //
57
+ // we do not abbreviate:
58
+ // - size
59
+
60
+
61
+ // Internal Types
62
+ // --------------
63
+
64
+ /**
65
+ * Internal grouping of 1-4 elements
66
+ *
67
+ * It is called digit since Okasaki (1998) calls finger trees "numerical operations".
68
+ */
69
+ type Digit[A] {
70
+ One(value: A)
71
+ Two(first: A, second: A)
72
+ Three(first: A, second: A, third: A)
73
+ Four(first: A, second: A, third: A, fourth: A)
74
+ }
75
+
76
+ /**
77
+ * Internal representation of a 2-3 tree
78
+ */
79
+ type Node[A] {
80
+ // These are necessary to avoid polymorphic recursion
81
+ Leaf2(first: A, second: A)
82
+ Leaf3(first: A, second: A, third: A)
83
+ Node2(size: Int, first: Node[A], second: Node[A])
84
+ Node3(size: Int, first: Node[A], second: Node[A], third: Node[A])
85
+ }
86
+
87
+ /**
88
+ * Internal duplicate of Seq
89
+ *
90
+ * splitting into two type parameters is necessary since our MLton backend does
91
+ * not support mutually recursive data type declarations.
92
+ */
93
+ type Finger[A, N] {
94
+ NoFinger()
95
+ SingleFinger(value: Node[A])
96
+ DeepFinger(size: Int, prefix: N, middle: Finger[A, N], suffix: N)
97
+ }
98
+
99
+ /**
100
+ * Internal
101
+ */
102
+ type Tree[A] = Finger[A, Digit[Node[A]]]
103
+
104
+ /**
105
+ * Internal
106
+ */
107
+ type TreeView[A] {
108
+ TreeIsEmpty()
109
+ TreeView(element: Node[A], rest: Tree[A])
110
+ }
111
+
112
+
113
+
114
+ // Measure
115
+ // -------
116
+
117
+ def size[A](node: Digit[A]): Int = node match {
118
+ case One(_) => 1
119
+ case Two(_, _) => 2
120
+ case Three(_, _, _) => 3
121
+ case Four(_, _, _, _) => 4
122
+ }
123
+
124
+ def size[A](node: Node[A]): Int = node match {
125
+ case Leaf2(_, _) => 2
126
+ case Leaf3(_, _, _) => 3
127
+ case Node2(size, _, _) => size
128
+ case Node3(size, _, _, _) => size
129
+ }
130
+
131
+ def sizeDeep[A](node: Digit[Node[A]]): Int = node match {
132
+ case One(a) => a.size
133
+ case Two(a, b) => a.size + b.size
134
+ case Three(a, b, c) => a.size + b.size + c.size
135
+ case Four(a, b, c, d) => a.size + b.size + c.size + d.size
136
+ }
137
+
138
+ def size[A](tree: Tree[A]): Int = tree match {
139
+ case NoFinger() => 0
140
+ case SingleFinger(value) => value.size
141
+ case DeepFinger(size, _, _, _) => size
142
+ }
143
+
144
+ /**
145
+ * The size of the given sequence
146
+ */
147
+ def size[A](seq: Seq[A]): Int = seq match {
148
+ case Empty() => 0
149
+ case Single(value) => 1
150
+ case Deep(size, _, _, _) => size
151
+ }
152
+
153
+
154
+ // Internal smart constructors
155
+ // ---------------------------
156
+
157
+ def deepFinger[A](prefix: Digit[Node[A]], middle: Tree[A], suffix: Digit[Node[A]]): Tree[A] =
158
+ DeepFinger(prefix.sizeDeep + middle.size + suffix.sizeDeep, prefix, middle, suffix)
159
+
160
+ def deep[A](prefix: Digit[A], middle: Tree[A], suffix: Digit[A]): Seq[A] =
161
+ Deep(prefix.size + middle.size + suffix.size, prefix, middle, suffix)
162
+
163
+ def node2[A](first: Node[A], second: Node[A]): Node[A] =
164
+ Node2(first.size + second.size, first, second)
165
+
166
+ def node3[A](first: Node[A], second: Node[A], third: Node[A]): Node[A] =
167
+ Node3(first.size + second.size + third.size, first, second, third)
168
+
169
+
170
+ // Adding an element to the left
171
+ // -----------------------------
172
+
173
+ def consFinger[A](head: Node[A], tail: Tree[A]): Tree[A] = tail match {
174
+ case NoFinger() => SingleFinger(head)
175
+ case SingleFinger(b) => deepFinger(One(head), NoFinger(), One(b))
176
+ case DeepFinger(_, One(b), m, s) => deepFinger(Two(head, b), m, s)
177
+ case DeepFinger(_, Two(b, c), m, s) => deepFinger(Three(head, b, c), m, s)
178
+ case DeepFinger(_, Three(b, c, d), m, s) => deepFinger(Four(head, b, c, d), m, s)
179
+ case DeepFinger(_, Four(b, c, d, e), m, s) =>
180
+ deepFinger(Two(head, b), consFinger(node3(c, d, e), m), s)
181
+ }
182
+
183
+ def cons[A](head: A, tail: Seq[A]): Seq[A] = tail match {
184
+ case Empty() => Single(head)
185
+ case Single(b) => Deep(2, One(head), NoFinger(), One(b))
186
+ case Deep(size, One(b), m, s) => Deep(size + 1, Two(head, b), m, s)
187
+ case Deep(size, Two(b, c), m, s) => Deep(size + 1, Three(head, b, c), m, s)
188
+ case Deep(size, Three(b, c, d), m, s) => Deep(size + 1, Four(head, b, c, d), m, s)
189
+ case Deep(size, Four(b, c, d, e), m, s) =>
190
+ Deep(size + 1, Two(head, b), consFinger(Leaf3(c, d, e), m), s)
191
+ }
192
+
193
+
194
+ // Adding an element to the right
195
+ // ------------------------------
196
+
197
+ def consFingerRight[A](init: Tree[A], last: Node[A]): Tree[A] = init match {
198
+ case NoFinger() => SingleFinger(last)
199
+ case SingleFinger(b) => deepFinger(One(b), NoFinger(), One(last))
200
+ case DeepFinger(_, p, m, One(b)) => deepFinger(p, m, Two(b, last))
201
+ case DeepFinger(_, p, m, Two(b, c)) => deepFinger(p, m, Three(b, c, last))
202
+ case DeepFinger(_, p, m, Three(b, c, d)) => deepFinger(p, m, Four(b, c, d, last))
203
+ case DeepFinger(_, p, m, Four(b, c, d, e)) =>
204
+ deepFinger(p, consFingerRight(m, node3(b, c, d)), Two(e, last))
205
+ }
206
+
207
+ def consRight[A](init: Seq[A], last: A): Seq[A] = init match {
208
+ case Empty() => Single(last)
209
+ case Single(b) => Deep(2, One(b), NoFinger(), One(last))
210
+ case Deep(size, p, m, One(b)) => Deep(size + 1, p, m, Two(b, last))
211
+ case Deep(size, p, m, Two(b, c)) => Deep(size + 1, p, m, Three(b, c, last))
212
+ case Deep(size, p, m, Three(b, c, d)) => Deep(size + 1, p, m, Four(b, c, d, last))
213
+ case Deep(size, p, m, Four(b, c, d, e)) =>
214
+ Deep(size + 1, p, consFingerRight(m, Leaf3(b, c, d)), Two(e, last))
215
+ }
216
+
217
+
218
+ // Splitting the sequence on the left
219
+ // ----------------------------------
220
+
221
+ def unconsFinger[A](seq: Tree[A]): TreeView[A] = seq match {
222
+ case NoFinger() => TreeIsEmpty()
223
+ case SingleFinger(v) => TreeView(v, NoFinger())
224
+ // TODO this is a tail-call-modulo-context
225
+ case DeepFinger(size, One(a), m, s) => TreeView(a, unconsFinger(m) match {
226
+ case TreeIsEmpty() => s.toTree
227
+ case TreeView(b, m2) => DeepFinger(size - a.size, b.toDigitNode, m2, s)
228
+ })
229
+ case DeepFinger(size, Two(a, b), m, s) => TreeView(a, DeepFinger(size - a.size, One(b), m, s))
230
+ case DeepFinger(size, Three(a, b, c), m, s) => TreeView(a, DeepFinger(size - a.size, Two(b, c), m, s))
231
+ case DeepFinger(size, Four(a, b, c, d), m, s) => TreeView(a, DeepFinger(size - a.size, Three(b, c, d), m, s))
232
+ }
233
+
234
+ // this could be called "uncons", "first", "front", "head", "popFront", "start", "popStart"
235
+ def uncons[A](seq: Seq[A]): View[A] = seq match {
236
+ case Empty() => IsEmpty()
237
+ case Single(v) => View(v, Empty())
238
+ case Deep(size, One(a), m, s) => View(a, unconsFinger(m) match {
239
+ case TreeIsEmpty() => s.toSeq
240
+ case TreeView(b, m2) => Deep(size - 1, b.toDigit, m2, s)
241
+ })
242
+ case Deep(size, Two(a, b), m, s) => View(a, Deep(size - 1, One(b), m, s))
243
+ case Deep(size, Three(a, b, c), m, s) => View(a, Deep(size - 1, Two(b, c), m, s))
244
+ case Deep(size, Four(a, b, c, d), m, s) => View(a, Deep(size - 1, Three(b, c, d), m, s))
245
+ }
246
+
247
+ def head[A](seq: Seq[A]): A / Exception[NoSuchElement] = seq.uncons match {
248
+ case IsEmpty() => raise(NoSuchElement(), "Calling `head` on empty sequence.")
249
+ case View(element, _) => element
250
+ }
251
+
252
+ def tail[A](seq: Seq[A]): Seq[A] / Exception[NoSuchElement] = seq.uncons match {
253
+ case IsEmpty() => raise(NoSuchElement(), "Calling `tail` on empty sequence.")
254
+ case View(element, rest) => rest
255
+ }
256
+
257
+
258
+ // Splitting the sequence on the right
259
+ // -----------------------------------
260
+
261
+ def unconsRightFinger[A](seq: Tree[A]): TreeView[A] = seq match {
262
+ case NoFinger() => TreeIsEmpty()
263
+ case SingleFinger(v) => TreeView(v, NoFinger())
264
+ // TODO this is a tail-call-modulo-context
265
+ case DeepFinger(size, p, m, One(a)) => TreeView(a, unconsRightFinger(m) match {
266
+ case TreeIsEmpty() => p.toTree
267
+ case TreeView(b, m2) => DeepFinger(size - a.size, p, m2, b.toDigitNode)
268
+ })
269
+ case DeepFinger(size, p, m, Two(a, b)) => TreeView(b, DeepFinger(size - b.size, p, m, One(a)))
270
+ case DeepFinger(size, p, m, Three(a, b, c)) => TreeView(c, DeepFinger(size - c.size, p, m, Two(a, b)))
271
+ case DeepFinger(size, p, m, Four(a, b, c, d)) => TreeView(d, DeepFinger(size - d.size, p, m, Three(a, b, c)))
272
+ }
273
+
274
+ // this could be called "uncons", "first", "front", "head", "popFront", "start", "popStart"
275
+ def unconsRight[A](seq: Seq[A]): View[A] = seq match {
276
+ case Empty() => IsEmpty()
277
+ case Single(v) => View(v, Empty())
278
+ case Deep(size, p, m, One(a)) => View(a, unconsFinger(m) match {
279
+ case TreeIsEmpty() => p.toSeq
280
+ case TreeView(b, m2) => Deep(size - 1, p, m2, b.toDigit)
281
+ })
282
+ case Deep(size, p, m, Two(a, b)) => View(b, Deep(size - 1, p, m, One(a)))
283
+ case Deep(size, p, m, Three(a, b, c)) => View(c, Deep(size - 1, p, m, Two(a, b)))
284
+ case Deep(size, p, m, Four(a, b, c, d)) => View(d, Deep(size - 1, p, m, Three(a, b, c)))
285
+ }
286
+
287
+
288
+ // Concatenating Sequences
289
+ // -----------------------
290
+
291
+ def concatTree[A](first: Tree[A], middle: List[Node[A]], second: Tree[A]): Tree[A] = {
292
+
293
+ // can we get rid of the list?
294
+
295
+ def prepend(nodes: List[Node[A]], tree: Tree[A]): Tree[A] = nodes match {
296
+ case Nil() => tree
297
+ case Cons(head, tail) => consFinger(head, prepend(tail, tree))
298
+ }
299
+
300
+ def append(tree: Tree[A], nodes: List[Node[A]]): Tree[A] = nodes match {
301
+ case Nil() => tree
302
+ case Cons(head, tail) => append(consFingerRight(tree, head), tail)
303
+ }
304
+
305
+ def consFinger(digit: Digit[Node[A]], tree: Tree[A]): Tree[A] = digit match {
306
+ case One(a) => consFinger(a, tree)
307
+ case Two(a, b) => consFinger(a, consFinger(b, tree))
308
+ case Three(a, b, c) => consFinger(a, consFinger(b, consFinger(c, tree)))
309
+ case Four(a, b, c, d) => consFinger(a, consFinger(b, consFinger(c, consFinger(d, tree))))
310
+ }
311
+
312
+ def toList(digit: Digit[Node[A]]): List[Node[A]] = digit match {
313
+ case One(a) => Cons(a, Nil())
314
+ case Two(a, b) => Cons(a, Cons(b, Nil()))
315
+ case Three(a, b, c) => Cons(a, Cons(b, Cons(c, Nil())))
316
+ case Four(a, b, c, d) => Cons(a, Cons(b, Cons(c, Cons(d, Nil()))))
317
+ }
318
+
319
+ def rebalance(nodes: List[Node[A]]): List[Node[A]] = nodes match {
320
+ case Cons(a, Cons(b, Nil())) => Cons(node2(a, b), Nil())
321
+ case Cons(a, Cons(b, Cons(c, Nil()))) => Cons(node3(a, b, c), Nil())
322
+ case Cons(a, Cons(b, Cons(c, Cons(d, Nil())))) => Cons(node2(a, b), Cons(node2(c, d), Nil()))
323
+ case Cons(a, Cons(b, Cons(c, rest))) => Cons(node3(a, b, c), rebalance(rest))
324
+ case _ => <>
325
+ }
326
+
327
+ def go(prefix: Tree[A], middle: List[Node[A]], suffix: Tree[A]): Tree[A] =
328
+ (prefix, suffix) match {
329
+ case (NoFinger(), s) => prepend(middle, s)
330
+ case (p, NoFinger()) => append(p, middle)
331
+ case (SingleFinger(v), s) => consFinger(v, prepend(middle, s))
332
+ case (p, SingleFinger(v)) => consFingerRight(append(p, middle), v)
333
+ case (DeepFinger(size1, p1, m1, s1), DeepFinger(size2, p2, m2, s2)) =>
334
+ val list = s1.toList.append(middle).append(p2.toList)
335
+ DeepFinger(size1 + size2, p1, go(m1, rebalance(list), m2), s2)
336
+ }
337
+
338
+ go(first, middle, second)
339
+ }
340
+
341
+ def concat[A](first: Seq[A], second: Seq[A]): Seq[A] = {
342
+ def rebalance(t: List[A]): List[Node[A]] = t match {
343
+ case Cons(a, Cons(b, Nil())) => Cons(Leaf2(a, b), Nil())
344
+ case Cons(a, Cons(b, Cons(c, Nil()))) => Cons(Leaf3(a, b, c), Nil())
345
+ case Cons(a, Cons(b, Cons(c, Cons(d, Nil())))) => Cons(Leaf2(a, b), Cons(Leaf2(c, d), Nil()))
346
+ case Cons(a, Cons(b, Cons(c, rest))) => Cons(Leaf3(a, b, c), rebalance(rest))
347
+ case _ => <>
348
+ }
349
+
350
+ (first, second) match {
351
+ case (Empty(), other) => other
352
+ case (other, Empty()) => other
353
+ case (Single(v), other) => cons(v, other)
354
+ case (other, Single(v)) => consRight(other, v)
355
+ case (Deep(size1, p1, m1, s1), Deep(size2, p2, m2, s2)) =>
356
+ Deep(size1 + size2, p1, concatTree(m1, rebalance(s1.toList.append(p2.toList)), m2), s2)
357
+ }
358
+ }
359
+
360
+
361
+ // Predicates
362
+ // ----------
363
+
364
+ def isEmpty[A](seq: Seq[A]): Bool = seq match {
365
+ case Empty() => true
366
+ case _ => false
367
+ }
368
+
369
+ def nonEmpty[A](seq: Seq[A]): Bool = seq match {
370
+ case Empty() => false
371
+ case _ => true
372
+ }
373
+
374
+ def reverse[A](seq: Seq[A]): Seq[A] = {
375
+
376
+ // invariant for all internal functions: element is in the sequence
377
+
378
+ // this is tail-recursive-modulo-context
379
+ def go(node: Node[A]): Node[A] = node match {
380
+ case Leaf2(a, b) => Leaf2(b, a)
381
+ case Leaf3(a, b, c) => Leaf3(c, b, a)
382
+ case Node2(size, a, b) => Node2(size, go(b), go(a))
383
+ case Node3(size, a, b, c) => Node3(size, go(c), go(b), go(a))
384
+ }
385
+ def go(digit: Digit[A]): Digit[A] = digit match {
386
+ case One(a) => One(a)
387
+ case Two(a, b) => Two(b, a)
388
+ case Three(a, b, c) => Three(c, b, a)
389
+ case Four(a, b, c, d) => Four(d, c, b, a)
390
+ }
391
+ def go(digits: Digit[Node[A]]): Digit[Node[A]] = digits match {
392
+ case One(a) => One(go(a))
393
+ case Two(a, b) => Two(go(b), go(a))
394
+ case Three(a, b, c) => Three(go(c), go(b), go(a))
395
+ case Four(a, b, c, d) => Four(go(d), go(c), go(b), go(a))
396
+ }
397
+ def go(tree: Tree[A]): Tree[A] = tree match {
398
+ case NoFinger() => NoFinger()
399
+ case SingleFinger(value) => SingleFinger(go(value))
400
+ case DeepFinger(size, p, m, s) => DeepFinger(size, go(s), go(m), go(p))
401
+ }
402
+
403
+ seq match {
404
+ case Empty() => Empty()
405
+ case Single(value) => Single(value)
406
+ case Deep(size, p, m, s) => Deep(size, go(s), go(m), go(p))
407
+ }
408
+ }
409
+
410
+
411
+ /**
412
+ * Random access
413
+ */
414
+ def index[A](seq: Seq[A], index: Int): A / Exception[NoSuchElement] = {
415
+
416
+ // invariant for all internal functions: element is in the sequence
417
+
418
+ def go(node: Node[A], index: Int): A = node match {
419
+ case Leaf2(a, b) => if (index == 0) a else b
420
+ case Leaf3(a, b, c) => if (index == 0) a else if (index == 1) b else c
421
+ case Node2(_, a, b) =>
422
+ val asize = a.size
423
+ if (index < asize) go(a, index) else go(b, index - asize)
424
+ case Node3(_, a, b, c) =>
425
+ val asize = a.size
426
+ if (index < asize) go(a, index) else {
427
+ val bsize = asize + b.size
428
+ if (index < bsize) go(b, index - asize) else go(c, index - bsize)
429
+ }
430
+ }
431
+ def go(digit: Digit[A], index: Int): A = digit match {
432
+ case One(a) => a
433
+ case Two(a, b) => if (index == 0) a else b
434
+ case Three(a, b, c) => if (index == 0) a else if (index == 1) b else c
435
+ case Four(a, b, c, d) => if (index == 0) a else if (index == 1) b else if (index == 2) c else d
436
+ }
437
+ def go(digits: Digit[Node[A]], index: Int): A = digits match {
438
+ case One(a) => go(a, index)
439
+ case Two(a, b) =>
440
+ val asize = a.size
441
+ if (index < asize) go(a, index) else go(b, index - asize)
442
+ case Three(a, b, c) =>
443
+ val asize = a.size
444
+ if (index < asize) go(a, index) else {
445
+ val bsize = asize + b.size
446
+ if (index < bsize) go(b, index - asize) else {
447
+ go(c, index - bsize)
448
+ }
449
+ }
450
+ case Four(a, b, c, d) =>
451
+ val asize = a.size
452
+ if (index < asize) go(a, index) else {
453
+ val bsize = asize + b.size
454
+ if (index < bsize) go(b, index - asize) else {
455
+ val csize = bsize + c.size
456
+ if (index < csize) go(c, index - bsize) else {
457
+ go(d, index - csize)
458
+ }
459
+ }
460
+ }
461
+ }
462
+ def go(tree: Tree[A], index: Int): A = tree match {
463
+ case NoFinger() => <{ "Cannot happen!" }>
464
+ case SingleFinger(value) => go(value, index)
465
+ case DeepFinger(_, p, m, s) =>
466
+ val psize = p.sizeDeep
467
+ if (index < psize) { go(p, index) } else {
468
+ val msize = psize + m.size
469
+ if (index < msize) { go(m, index - psize) }
470
+ else { go(s, index - msize) }
471
+ }
472
+ }
473
+
474
+ if (index >= seq.size) raise(NoSuchElement(), "...")
475
+ else seq match {
476
+ case Empty() => <{ "Cannot happen!" }>
477
+ case Single(v) => v // has to be the right one due to the check above
478
+ case Deep(_, p, m, s) =>
479
+ val psize = p.size
480
+ if (index < psize) { go(p, index) } else {
481
+ val msize = psize + m.size
482
+ if (index < msize) { go(m, index - psize) }
483
+ else { go(s, index - msize) }
484
+ }
485
+ }
486
+ }
487
+
488
+ /**
489
+ * Random access
490
+ */
491
+ def update[A](seq: Seq[A], index: Int, value: A): Seq[A] / Exception[NoSuchElement] = {
492
+
493
+ // invariant for all internal functions: element is in the sequence
494
+
495
+ // this is tail-recursive-modulo-context
496
+ def go(node: Node[A], index: Int): Node[A] = node match {
497
+ case Leaf2(a, b) => if (index == 0) Leaf2(value, b) else Leaf2(a, value)
498
+ case Leaf3(a, b, c) => if (index == 0) Leaf3(value, b, c) else if (index == 1) Leaf3(a, value, c) else Leaf3(a, b, value)
499
+ case Node2(size, a, b) =>
500
+ val asize = a.size
501
+ if (index < asize) Node2(size, go(a, index), b) else Node2(size, a, go(b, index - asize))
502
+ case Node3(size, a, b, c) =>
503
+ val asize = a.size
504
+ if (index < asize) Node3(size, go(a, index), b, c) else {
505
+ val bsize = asize + b.size
506
+ if (index < bsize) Node3(size, a, go(b, index - asize), c) else Node3(size, a, b, go(c, index - bsize))
507
+ }
508
+ }
509
+ def go(digit: Digit[A], index: Int): Digit[A] = digit match {
510
+ case One(a) => One(value)
511
+ case Two(a, b) => if (index == 0) Two(value, b) else Two(a, value)
512
+ case Three(a, b, c) => if (index == 0) Three(value, b, c) else if (index == 1) Three(a, value, c) else Three(a, b, value)
513
+ case Four(a, b, c, d) => if (index == 0) Four(value, b, c, d) else if (index == 1) Four(a, value, c, d) else if (index == 2) Four(a, b, value, d) else Four(a, b, c, value)
514
+ }
515
+ def go(digits: Digit[Node[A]], index: Int): Digit[Node[A]] = digits match {
516
+ case One(a) => One(go(a, index))
517
+ case Two(a, b) =>
518
+ val asize = a.size
519
+ if (index < asize) Two(go(a, index), b) else Two(a, go(b, index - asize))
520
+ case Three(a, b, c) =>
521
+ val asize = a.size
522
+ if (index < asize) Three(go(a, index), b, c) else {
523
+ val bsize = asize + b.size
524
+ if (index < bsize) Three(a, go(b, index - asize), c) else {
525
+ Three(a, b, go(c, index - bsize))
526
+ }
527
+ }
528
+ case Four(a, b, c, d) =>
529
+ val asize = a.size
530
+ if (index < asize) Four(go(a, index), b, c, d) else {
531
+ val bsize = asize + b.size
532
+ if (index < bsize) Four(a, go(b, index - asize), c, d) else {
533
+ val csize = bsize + c.size
534
+ if (index < csize) Four(a, b, go(c, index - bsize), d) else {
535
+ Four(a, b, c, go(d, index - csize))
536
+ }
537
+ }
538
+ }
539
+ }
540
+ def go(tree: Tree[A], index: Int): Tree[A] = tree match {
541
+ case NoFinger() => <{ "Cannot happen!" }>
542
+ case SingleFinger(value) => SingleFinger(go(value, index))
543
+ case DeepFinger(size, p, m, s) =>
544
+ val psize = p.sizeDeep
545
+ if (index < psize) { DeepFinger(size, go(p, index), m, s) } else {
546
+ val msize = psize + m.size
547
+ if (index < msize) { DeepFinger(size, p, go(m, index - psize), s) }
548
+ else { DeepFinger(size, p, m, go(s, index - msize)) }
549
+ }
550
+ }
551
+
552
+ if (index >= seq.size) raise(NoSuchElement(), "...")
553
+ else seq match {
554
+ case Empty() => <{ "Cannot happen!" }>
555
+ case Single(_) => Single(value) // has to be the right one due to the check above
556
+ case Deep(size, p, m, s) =>
557
+ val psize = p.size
558
+ if (index < psize) { Deep(size, go(p, index), m, s) } else {
559
+ val msize = psize + m.size
560
+ if (index < msize) { Deep(size, p, go(m, index - psize), s) }
561
+ else { Deep(size, p, m, go(s, index - msize)) }
562
+ }
563
+ }
564
+ }
565
+
566
+
567
+ def each[A](seq: Seq[A]) { consume: (A) => Unit }: Unit = {
568
+
569
+ def go(digit: Digit[A]): Unit = digit match {
570
+ case One(a) => consume(a)
571
+ case Two(a, b) => consume(a); consume(b)
572
+ case Three(a, b, c) => consume(a); consume(b); consume(c)
573
+ case Four(a, b, c, d) => consume(a); consume(b); consume(c); consume(d)
574
+ }
575
+
576
+ def go(node: Node[A]): Unit = node match {
577
+ case Leaf2(a, b) => consume(a); consume(b)
578
+ case Leaf3(a, b, c) => consume(a); consume(b); consume(c)
579
+ case Node2(_, a, b) => go(a); go(b)
580
+ case Node3(_, a, b, c) => go(a); go(b); go(c)
581
+ }
582
+
583
+ def go(digit: Digit[Node[A]]): Unit = digit match {
584
+ case One(a) => go(a)
585
+ case Two(a, b) => go(a); go(b)
586
+ case Three(a, b, c) => go(a); go(b); go(c)
587
+ case Four(a, b, c, d) => go(a); go(b); go(c); go(d)
588
+ }
589
+
590
+ def go(tree: Tree[A]): Unit = tree match {
591
+ case NoFinger() => ()
592
+ case SingleFinger(v) => go(v)
593
+ case DeepFinger(_, p, m, s) => go(p); go(m); go(s)
594
+ }
595
+
596
+ seq match {
597
+ case Empty() => ()
598
+ case Single(v) => consume(v)
599
+ case Deep(_, p, m, s) => go(p); go(m); go(s)
600
+ }
601
+ }
602
+
603
+ def each[A](seq: Seq[A]) { f: (A) {Control} => Unit }: Unit = try {
604
+ seq.each { (el) =>
605
+ try { f(el) {inner} } with inner: Control {
606
+ def break() = outer.break()
607
+ def continue() = ()
608
+ }
609
+ }
610
+ } with outer: Control {
611
+ def break() = ()
612
+ def continue() = ()
613
+ }
614
+
615
+ def eachReverse[A](seq: Seq[A]) { consume: A => Unit }: Unit = {
616
+
617
+ def go(digit: Digit[A]): Unit = digit match {
618
+ case One(a) => consume(a)
619
+ case Two(a, b) => consume(b); consume(a)
620
+ case Three(a, b, c) => consume(c); consume(b); consume(a)
621
+ case Four(a, b, c, d) => consume(d); consume(c); consume(b); consume(a)
622
+ }
623
+
624
+ def go(node: Node[A]): Unit = node match {
625
+ case Leaf2(a, b) => consume(b); consume(a)
626
+ case Leaf3(a, b, c) => consume(c); consume(b); consume(a)
627
+ case Node2(_, a, b) => go(b); go(a)
628
+ case Node3(_, a, b, c) => go(c); go(b); go(a)
629
+ }
630
+
631
+ def go(digit: Digit[Node[A]]): Unit = digit match {
632
+ case One(a) => go(a)
633
+ case Two(a, b) => go(b); go(a)
634
+ case Three(a, b, c) => go(c); go(b); go(a)
635
+ case Four(a, b, c, d) => go(d); go(c); go(b); go(a)
636
+ }
637
+
638
+ def go(tree: Tree[A]): Unit = tree match {
639
+ case NoFinger() => ()
640
+ case SingleFinger(v) => go(v)
641
+ case DeepFinger(_, p, m, s) => go(s); go(m); go(p)
642
+ }
643
+
644
+ seq match {
645
+ case Empty() => ()
646
+ case Single(v) => consume(v)
647
+ case Deep(_, p, m, s) => go(s); go(m); go(p)
648
+ }
649
+ }
650
+
651
+ def eachReverse[A](seq: Seq[A]) { f: (A) {Control} => Unit }: Unit = try {
652
+ seq.eachReverse { (el) =>
653
+ try { f(el) {inner} } with inner: Control {
654
+ def break() = outer.break()
655
+ def continue() = ()
656
+ }
657
+ }
658
+ } with outer: Control {
659
+ def break() = ()
660
+ def continue() = ()
661
+ }
662
+
663
+ def toList[A](seq: Seq[A]): List[A] = {
664
+ var list: List[A] = Nil()
665
+ seq.eachReverse { el => list = Cons(el, list) }
666
+ list
667
+ }
668
+
669
+ def toSeq[A](l: List[A]): Seq[A] = {
670
+ def go(l: List[A], acc: Seq[A]): Seq[A] = l match {
671
+ case Nil() => acc
672
+ case Cons(head, tail) => go(tail, consRight(acc, head))
673
+ }
674
+ go(l, Empty())
675
+ }
676
+
677
+
678
+ record Split[A, R](prefix: R, element: A, suffix: R)
679
+
680
+ def splitAt[A](seq: Seq[A], index: Int): (Seq[A], Seq[A]) / Exception[IndexOutOfBounds] = {
681
+
682
+ // invariant index is in digit
683
+ def go(digit: Digit[A], index: Int): Split[A, List[A]] = digit match {
684
+ case One(a) => Split([], a, [])
685
+ case Two(a, b) => if (index == 0) Split([], a, [b]) else Split([a], b, [])
686
+ case Three(a, b, c) =>
687
+ if (index == 0) Split([], a, [b, c])
688
+ else if (index == 1) Split([a], b, [c])
689
+ else Split([a, b], c, [])
690
+ case Four(a, b, c, d) =>
691
+ if (index == 0) Split([], a, [b, c, d])
692
+ else if (index == 1) Split([a], b, [c, d])
693
+ else if (index == 2) Split([a, b], c, [d])
694
+ else Split([a, b, c], d, [])
695
+ }
696
+
697
+ def go(digit: Digit[Node[A]], index: Int): Split[Node[A], List[Node[A]]] = digit match {
698
+ case One(a) => Split([], a, [])
699
+ case Two(a, b) =>
700
+ val asize = a.size
701
+ if (index < asize) Split([], a, [b]) else Split([a], b, [])
702
+ case Three(a, b, c) =>
703
+ val asize = a.size
704
+ if (index < asize) Split([], a, [b, c])
705
+ else {
706
+ val bsize = asize + b.size
707
+ if (index < bsize) Split([a], b, [c])
708
+ else Split([a, b], c, [])
709
+ }
710
+ case Four(a, b, c, d) =>
711
+ val asize = a.size
712
+ if (index < asize) Split([], a, [b, c, d])
713
+ else {
714
+ val bsize = asize + b.size
715
+ if (index < bsize) Split([a], b, [c, d])
716
+ else {
717
+ val csize = bsize + c.size
718
+ if (index < csize) Split([a, b], c, [d])
719
+ else Split([a, b, c], d, [])
720
+ }
721
+ }
722
+ }
723
+
724
+ def left(p: List[Node[A]], m: Tree[A], s: Digit[Node[A]]): Tree[A] = p match {
725
+ case Nil() => m.unconsFinger match {
726
+ case TreeIsEmpty() => s.toTree
727
+ case TreeView(a, m2) => deepFinger(a.toDigitNode, m2, s)
728
+ }
729
+ case _ => deepFinger(p.toDigitNode, m, s)
730
+ }
731
+
732
+ def left(p: List[A], m: Tree[A], s: Digit[A]): Seq[A] = p match {
733
+ case Nil() => m.unconsFinger match {
734
+ case TreeIsEmpty() => s.toSeq
735
+ case TreeView(a, m2) => deep(a.toDigit, m2, s)
736
+ }
737
+ case _ => deep(p.toDigitNode, m, s)
738
+ }
739
+ def right(p: Digit[A], m: Tree[A], s: List[A]): Seq[A] = s match {
740
+ case Nil() => m.unconsRightFinger match {
741
+ case TreeIsEmpty() => p.toSeq
742
+ case TreeView(a, m2) => deep(p, m2, a.toDigit)
743
+ }
744
+ case _ => deep(p, m, s.toDigitNode)
745
+ }
746
+
747
+
748
+ def right(p: Digit[Node[A]], m: Tree[A], s: List[Node[A]]): Tree[A] = s match {
749
+ case Nil() => m.unconsRightFinger match {
750
+ case TreeIsEmpty() => p.toTree
751
+ case TreeView(a, m2) => deepFinger(p, m2, a.toDigitNode)
752
+ }
753
+ case _ => deepFinger(p, m, s.toDigitNode)
754
+ }
755
+
756
+ def go(tree: Tree[A], index: Int): Split[Node[A], Tree[A]] = tree match {
757
+ case NoFinger() => println("Cannot happen!"); <{ "Cannot happen!" }>
758
+ case SingleFinger(value) => Split(NoFinger(), value, NoFinger())
759
+ case DeepFinger(size, p, m, s) =>
760
+ val psize = p.sizeDeep;
761
+ // It is in the prefix
762
+ if (index < psize) {
763
+ val Split(pp, v, ps) = go(p, index);
764
+ Split(pp.toTree, v, left(ps, m, s))
765
+ } else {
766
+ val msize = psize + m.size
767
+ // It is somewhere in the spine
768
+ if (index < msize) {
769
+ val Split(mp, v, ms) = go(m, index - psize);
770
+ val mpsize = psize + mp.size;
771
+ val Split(vp, w, vs) = go(v.toDigitNode, index - mpsize);
772
+ Split(right(p, mp, vp), w, left(vs, ms, s))
773
+ // It is somewhere in the suffix
774
+ } else {
775
+ val Split(sp, v, ss) = go(s, index - msize)
776
+ Split(right(p, m, sp), v, ss.toTree)
777
+ }
778
+ }
779
+ }
780
+
781
+ if (index < 0) {
782
+ do raise(IndexOutOfBounds(), "...")
783
+ } else if (index >= seq.size) {
784
+ (seq, Empty())
785
+ } else seq match {
786
+ case Empty() => (Empty(), Empty())
787
+ case Single(v) => (Empty(), seq)
788
+ case Deep(size, p, m, s) =>
789
+ val psize = p.size;
790
+ // It is in the prefix
791
+ if (index < psize) {
792
+ val Split(pp, v, ps) = go(p, index);
793
+ (toSeq(pp), left(Cons(v, ps), m, s))
794
+ } else {
795
+ val msize = psize + m.size
796
+ // It is somewhere in the spine
797
+ if (index < msize) {
798
+ val Split(mp, v, ms) = go(m, index - psize);
799
+ val mpsize = psize + mp.size;
800
+ val Split(vp, w, vs) = go(v.toDigit, index - mpsize);
801
+ (right(p, mp, vp), left(Cons(w, vs), ms, s))
802
+ // It is somewhere in the suffix
803
+ } else {
804
+ val Split(sp, v, ss) = go(s, index - msize);
805
+ (right(p, m, sp), Cons(v, ss).toSeq)
806
+ }
807
+ }
808
+ }
809
+ }
810
+
811
+
812
+ def insert[A](seq: Seq[A], value: A, index: Int): Seq[A] / Exception[IndexOutOfBounds] =
813
+ splitAt(seq, index) match {
814
+ case (prefix, suffix) => prefix.concat(cons(value, suffix))
815
+ }
816
+
817
+
818
+
819
+ // Internal conversions
820
+ // --------------------
821
+
822
+ def toTree[A](digit: Digit[Node[A]]): Tree[A] = digit match {
823
+ case One(a) => SingleFinger(a)
824
+ case Two(a, b) => deepFinger(One(a), NoFinger(), One(b))
825
+ case Three(a, b, c) => deepFinger(Two(a, b), NoFinger(), One(c))
826
+ case Four(a, b, c, d) => deepFinger(Three(a, b, c), NoFinger(), One(d))
827
+ }
828
+
829
+ def toTree[A](digit: List[Node[A]]): Tree[A] = digit match {
830
+ case Nil() => NoFinger()
831
+ case Cons(a, Nil()) => SingleFinger(a)
832
+ case Cons(a, Cons(b, Nil())) => deepFinger(One(a), NoFinger(), One(b))
833
+ case Cons(a, Cons(b, Cons(c, Nil()))) => deepFinger(Two(a, b), NoFinger(), One(c))
834
+ case Cons(a, Cons(b, Cons(c, Cons(d, Nil())))) => deepFinger(Three(a, b, c), NoFinger(), One(d))
835
+ case _ => <>
836
+ }
837
+
838
+ def toSeq[A](d: Digit[A]): Seq[A] = d match {
839
+ case One(a) => Single(a)
840
+ case Two(a, b) => Deep(2, One(a), NoFinger(), One(b))
841
+ case Three(a, b, c) => Deep(3, Two(a, b), NoFinger(), One(c))
842
+ case Four(a, b, c, d) => Deep(4, Three(a, b, c), NoFinger(), One(d))
843
+ }
844
+
845
+ def toDigitNode[A](n: Node[A]): Digit[Node[A]] = n match {
846
+ case Node2(_, a, b) => Two(a, b)
847
+ case Node3(_, a, b, c) => Three(a, b, c)
848
+ case _ => <{ "Should not happen" }>
849
+ }
850
+
851
+ def toDigitNode[A](n: List[A]): Digit[A] = n match {
852
+ case Cons(a, Nil()) => One(a)
853
+ case Cons(a, Cons(b, Nil())) => Two(a, b)
854
+ case Cons(a, Cons(b, Cons(c, Nil()))) => Three(a, b, c)
855
+ case Cons(a, Cons(b, Cons(c, Cons(d, Nil())))) => Four(a, b, c, d)
856
+ case _ => <{ "Should not happen" }>
857
+ }
858
+
859
+ def toDigit[A](n: Node[A]): Digit[A] = n match {
860
+ case Leaf2(a, b) => Two(a, b)
861
+ case Leaf3(a, b, c) => Three(a, b, c)
862
+ case _ => <{ "Should not happen" }>
863
+ }
864
+
865
+ def toList[A](digit: Digit[A]): List[A] = digit match {
866
+ case One(a) => Cons(a, Nil())
867
+ case Two(a, b) => Cons(a, Cons(b, Nil()))
868
+ case Three(a, b, c) => Cons(a, Cons(b, Cons(c, Nil())))
869
+ case Four(a, b, c, d) => Cons(a, Cons(b, Cons(c, Cons(d, Nil()))))
870
+ }
871
+
872
+ def map[A, B](seq: Seq[A]) { f: A => B }: Seq[B] = {
873
+ var result: Seq[B] = Empty()
874
+ seq.each { a => result = result.consRight(f(a)) }
875
+ result
876
+ }
877
+
878
+ def map[A, B](seq: Seq[A]) { f: (A) {Control} => B }: Seq[B] = {
879
+ var result: Seq[B] = Empty()
880
+ seq.each { (a) {label} => result = result.consRight(f(a) {label}) }
881
+ result
882
+ }
883
+
884
+
885
+ // TODO iterator interface
886
+ //
887
+
888
+ // interface Iterator[A] {
889
+ // def value(): Option[A]
890
+ // def next(): Unit
891
+ // }
892
+
893
+ // interface Generator[A] {
894
+ // def yield(value: A): Unit
895
+ // }
896
+
897
+ // def iterate[A, R](seq: Seq[A]) { prog: {Iterator[A]} => R }: R = {
898
+
899
+ // var k: Unit => Unit at {} = fun(unit: Unit) { () }
900
+ // var v: Option[A] = None()
901
+
902
+ // try { seq.each { el => do yield(el) } } with Generator[A] {
903
+ // def yield(value) = { v = Some(value); k = box resume }
904
+ // }
905
+
906
+ // new Iterator[A] {
907
+ // def value() = v
908
+ // def next() = (unbox k)(())
909
+ // }
910
+ // }
911
+
912
+
913
+ // TODO equality comparison
914
+ //