@effekt-lang/effekt 0.2.1 → 0.2.2
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/LICENSE +21 -0
- package/README.md +36 -0
- package/bin/effekt +0 -0
- package/bin/effekt.sh +2 -0
- package/libraries/chez/THIRD-PARTY.txt +11 -0
- package/libraries/chez/callcc/datatype.ss +188 -0
- package/libraries/chez/callcc/effekt.effekt +221 -0
- package/libraries/chez/callcc/effekt.ss +31 -0
- package/libraries/chez/callcc/seq.ss +44 -0
- package/libraries/chez/callcc/seq0.ss +69 -0
- package/libraries/chez/callcc/tail.ss +76 -0
- package/libraries/chez/callcc/tail0.ss +89 -0
- package/libraries/chez/common/effekt_matching.ss +100 -0
- package/libraries/chez/common/effekt_primitives.ss +97 -0
- package/libraries/chez/common/immutable/cslist.effekt +31 -0
- package/libraries/chez/common/immutable/dequeue.effekt +78 -0
- package/libraries/chez/common/immutable/list.effekt +643 -0
- package/libraries/chez/common/immutable/option.effekt +39 -0
- package/libraries/chez/common/immutable/result.effekt +29 -0
- package/libraries/chez/common/io/args.effekt +20 -0
- package/libraries/chez/common/mutable/array.effekt +27 -0
- package/libraries/chez/common/mutable/dict.effekt +30 -0
- package/libraries/chez/common/mutable/heap.effekt +12 -0
- package/libraries/chez/common/test.effekt +59 -0
- package/libraries/chez/common/text/pregexp.scm +772 -0
- package/libraries/chez/common/text/regex.effekt +33 -0
- package/libraries/chez/common/text/string.effekt +46 -0
- package/libraries/chez/lift/effekt.effekt +217 -0
- package/libraries/chez/lift/effekt.ss +118 -0
- package/libraries/chez/monadic/effekt.effekt +218 -0
- package/libraries/chez/monadic/effekt.ss +84 -0
- package/libraries/chez/monadic/seq0.ss +76 -0
- package/libraries/js/effekt.effekt +284 -0
- package/libraries/js/effekt_builtins.js +26 -0
- package/libraries/js/effekt_matching.js +79 -0
- package/libraries/js/effekt_runtime.js +385 -0
- package/libraries/js/immutable/dequeue.effekt +78 -0
- package/libraries/js/immutable/list.effekt +643 -0
- package/libraries/js/immutable/option.effekt +49 -0
- package/libraries/js/immutable/result.effekt +29 -0
- package/libraries/js/io/args.effekt +9 -0
- package/libraries/js/io/async.effekt +28 -0
- package/libraries/js/io/async.js +2 -0
- package/libraries/js/io/file.effekt +50 -0
- package/libraries/js/io/file_include.js +13 -0
- package/libraries/js/mutable/array.effekt +98 -0
- package/libraries/js/mutable/heap.effekt +32 -0
- package/libraries/js/mutable/map.effekt +32 -0
- package/libraries/js/test.effekt +59 -0
- package/libraries/js/text/regex.effekt +34 -0
- package/libraries/js/text/string.effekt +64 -0
- package/libraries/js/unsafe/cont.effekt +11 -0
- package/libraries/js/web/dom.effekt +45 -0
- package/libraries/llvm/buffer.c +181 -0
- package/libraries/llvm/effekt.effekt +243 -0
- package/libraries/llvm/forward-declare-c.ll +24 -0
- package/libraries/llvm/hole.c +11 -0
- package/libraries/llvm/immutable/list.effekt +678 -0
- package/libraries/llvm/immutable/option.effekt +53 -0
- package/libraries/llvm/immutable/result.effekt +29 -0
- package/libraries/llvm/io/args.effekt +24 -0
- package/libraries/llvm/io.c +24 -0
- package/libraries/llvm/main.c +39 -0
- package/libraries/llvm/rts.ll +619 -0
- package/libraries/llvm/sanity.c +16 -0
- package/libraries/llvm/text/string.effekt +179 -0
- package/libraries/llvm/types.c +20 -0
- package/libraries/ml/effekt.effekt +267 -0
- package/libraries/ml/effekt.sml +63 -0
- package/libraries/ml/immutable/dequeue.effekt +81 -0
- package/libraries/ml/immutable/list.effekt +674 -0
- package/libraries/ml/immutable/option.effekt +53 -0
- package/libraries/ml/immutable/result.effekt +29 -0
- package/libraries/ml/immutable/seq.effekt +903 -0
- package/libraries/ml/internal/option.effekt +18 -0
- package/libraries/ml/io/args.effekt +41 -0
- package/libraries/ml/mutable/array.effekt +43 -0
- package/libraries/ml/random.effekt +85 -0
- package/libraries/ml/test.effekt +60 -0
- package/libraries/ml/text/regex.effekt +107 -0
- package/libraries/ml/text/string.effekt +81 -0
- package/licenses/THIRD-PARTY.txt +21 -0
- package/licenses/apache-2.0 - license-2.0.txt +202 -0
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +61 -0
- package/licenses/kiama-license.txt +373 -0
- package/licenses/kiama-readme.txt +186 -0
- package/licenses/mit license - mit-license.html +769 -0
- package/licenses/the apache software license, version 2.0 - license-2.0.txt +202 -0
- package/licenses/the bsd license - bsd-license.html +762 -0
- package/licenses/the mit license - mit.html +769 -0
- package/package.json +26 -18
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
module immutable/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]): Boolean = seq match {
|
|
365
|
+
case Empty() => true
|
|
366
|
+
case _ => false
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
def nonEmpty[A](seq: Seq[A]): Boolean = 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
|
+
def each[A](seq: Seq[A]) { f: A => Unit / Control }: Unit = try {
|
|
567
|
+
|
|
568
|
+
def consume(a: A): Unit =
|
|
569
|
+
try { f(a) } with Control {
|
|
570
|
+
def break() = outer.break()
|
|
571
|
+
def continue() = ()
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
def go(digit: Digit[A]): Unit = digit match {
|
|
575
|
+
case One(a) => consume(a)
|
|
576
|
+
case Two(a, b) => consume(a); consume(b)
|
|
577
|
+
case Three(a, b, c) => consume(a); consume(b); consume(c)
|
|
578
|
+
case Four(a, b, c, d) => consume(a); consume(b); consume(c); consume(d)
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
def go(node: Node[A]): Unit = node match {
|
|
582
|
+
case Leaf2(a, b) => consume(a); consume(b)
|
|
583
|
+
case Leaf3(a, b, c) => consume(a); consume(b); consume(c)
|
|
584
|
+
case Node2(_, a, b) => go(a); go(b)
|
|
585
|
+
case Node3(_, a, b, c) => go(a); go(b); go(c)
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
def go(digit: Digit[Node[A]]): Unit = digit match {
|
|
589
|
+
case One(a) => go(a)
|
|
590
|
+
case Two(a, b) => go(a); go(b)
|
|
591
|
+
case Three(a, b, c) => go(a); go(b); go(c)
|
|
592
|
+
case Four(a, b, c, d) => go(a); go(b); go(c); go(d)
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
def go(tree: Tree[A]): Unit = tree match {
|
|
596
|
+
case NoFinger() => ()
|
|
597
|
+
case SingleFinger(v) => go(v)
|
|
598
|
+
case DeepFinger(_, p, m, s) => go(p); go(m); go(s)
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
seq match {
|
|
602
|
+
case Empty() => ()
|
|
603
|
+
case Single(v) => consume(v)
|
|
604
|
+
case Deep(_, p, m, s) => go(p); go(m); go(s)
|
|
605
|
+
}
|
|
606
|
+
} with outer: Control {
|
|
607
|
+
def break() = ()
|
|
608
|
+
def continue() = ()
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
def eachReverse[A](seq: Seq[A]) { f: A => Unit / Control }: Unit = try {
|
|
612
|
+
|
|
613
|
+
def consume(a: A): Unit =
|
|
614
|
+
try { f(a) } with Control {
|
|
615
|
+
def break() = outer.break()
|
|
616
|
+
def continue() = ()
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
def go(digit: Digit[A]): Unit = digit match {
|
|
620
|
+
case One(a) => consume(a)
|
|
621
|
+
case Two(a, b) => consume(b); consume(a)
|
|
622
|
+
case Three(a, b, c) => consume(c); consume(b); consume(a)
|
|
623
|
+
case Four(a, b, c, d) => consume(d); consume(c); consume(b); consume(a)
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
def go(node: Node[A]): Unit = node match {
|
|
627
|
+
case Leaf2(a, b) => consume(b); consume(a)
|
|
628
|
+
case Leaf3(a, b, c) => consume(c); consume(b); consume(a)
|
|
629
|
+
case Node2(_, a, b) => go(b); go(a)
|
|
630
|
+
case Node3(_, a, b, c) => go(c); go(b); go(a)
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
def go(digit: Digit[Node[A]]): Unit = digit match {
|
|
634
|
+
case One(a) => go(a)
|
|
635
|
+
case Two(a, b) => go(b); go(a)
|
|
636
|
+
case Three(a, b, c) => go(c); go(b); go(a)
|
|
637
|
+
case Four(a, b, c, d) => go(d); go(c); go(b); go(a)
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
def go(tree: Tree[A]): Unit = tree match {
|
|
641
|
+
case NoFinger() => ()
|
|
642
|
+
case SingleFinger(v) => go(v)
|
|
643
|
+
case DeepFinger(_, p, m, s) => go(s); go(m); go(p)
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
seq match {
|
|
647
|
+
case Empty() => ()
|
|
648
|
+
case Single(v) => consume(v)
|
|
649
|
+
case Deep(_, p, m, s) => go(s); go(m); go(p)
|
|
650
|
+
}
|
|
651
|
+
} with outer: Control {
|
|
652
|
+
def break() = ()
|
|
653
|
+
def continue() = ()
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
def toList[A](seq: Seq[A]): List[A] = {
|
|
657
|
+
var list: List[A] = Nil()
|
|
658
|
+
seq.eachReverse { el => list = Cons(el, list) }
|
|
659
|
+
list
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
def toSeq[A](l: List[A]): Seq[A] = {
|
|
663
|
+
def go(l: List[A], acc: Seq[A]): Seq[A] = l match {
|
|
664
|
+
case Nil() => acc
|
|
665
|
+
case Cons(head, tail) => go(tail, consRight(acc, head))
|
|
666
|
+
}
|
|
667
|
+
go(l, Empty())
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
record Split[A, R](prefix: R, element: A, suffix: R)
|
|
674
|
+
|
|
675
|
+
def splitAt[A](seq: Seq[A], index: Int): (Seq[A], Seq[A]) / Exception[IndexOutOfBounds] = {
|
|
676
|
+
|
|
677
|
+
// invariant index is in digit
|
|
678
|
+
def go(digit: Digit[A], index: Int): Split[A, List[A]] = digit match {
|
|
679
|
+
case One(a) => Split([], a, [])
|
|
680
|
+
case Two(a, b) => if (index == 0) Split([], a, [b]) else Split([a], b, [])
|
|
681
|
+
case Three(a, b, c) =>
|
|
682
|
+
if (index == 0) Split([], a, [b, c])
|
|
683
|
+
else if (index == 1) Split([a], b, [c])
|
|
684
|
+
else Split([a, b], c, [])
|
|
685
|
+
case Four(a, b, c, d) =>
|
|
686
|
+
if (index == 0) Split([], a, [b, c, d])
|
|
687
|
+
else if (index == 1) Split([a], b, [c, d])
|
|
688
|
+
else if (index == 2) Split([a, b], c, [d])
|
|
689
|
+
else Split([a, b, c], d, [])
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
def go(digit: Digit[Node[A]], index: Int): Split[Node[A], List[Node[A]]] = digit match {
|
|
693
|
+
case One(a) => Split([], a, [])
|
|
694
|
+
case Two(a, b) =>
|
|
695
|
+
val asize = a.size
|
|
696
|
+
if (index < asize) Split([], a, [b]) else Split([a], b, [])
|
|
697
|
+
case Three(a, b, c) =>
|
|
698
|
+
val asize = a.size
|
|
699
|
+
if (index < asize) Split([], a, [b, c])
|
|
700
|
+
else {
|
|
701
|
+
val bsize = asize + b.size
|
|
702
|
+
if (index < bsize) Split([a], b, [c])
|
|
703
|
+
else Split([a, b], c, [])
|
|
704
|
+
}
|
|
705
|
+
case Four(a, b, c, d) =>
|
|
706
|
+
val asize = a.size
|
|
707
|
+
if (index < asize) Split([], a, [b, c, d])
|
|
708
|
+
else {
|
|
709
|
+
val bsize = asize + b.size
|
|
710
|
+
if (index < bsize) Split([a], b, [c, d])
|
|
711
|
+
else {
|
|
712
|
+
val csize = bsize + c.size
|
|
713
|
+
if (index < csize) Split([a, b], c, [d])
|
|
714
|
+
else Split([a, b, c], d, [])
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
def left(p: List[Node[A]], m: Tree[A], s: Digit[Node[A]]): Tree[A] = p match {
|
|
720
|
+
case Nil() => m.unconsFinger match {
|
|
721
|
+
case TreeIsEmpty() => s.toTree
|
|
722
|
+
case TreeView(a, m2) => deepFinger(a.toDigitNode, m2, s)
|
|
723
|
+
}
|
|
724
|
+
case _ => deepFinger(p.toDigitNode, m, s)
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
def left(p: List[A], m: Tree[A], s: Digit[A]): Seq[A] = p match {
|
|
728
|
+
case Nil() => m.unconsFinger match {
|
|
729
|
+
case TreeIsEmpty() => s.toSeq
|
|
730
|
+
case TreeView(a, m2) => deep(a.toDigit, m2, s)
|
|
731
|
+
}
|
|
732
|
+
case _ => deep(p.toDigitNode, m, s)
|
|
733
|
+
}
|
|
734
|
+
def right(p: Digit[A], m: Tree[A], s: List[A]): Seq[A] = s match {
|
|
735
|
+
case Nil() => m.unconsRightFinger match {
|
|
736
|
+
case TreeIsEmpty() => p.toSeq
|
|
737
|
+
case TreeView(a, m2) => deep(p, m2, a.toDigit)
|
|
738
|
+
}
|
|
739
|
+
case _ => deep(p, m, s.toDigitNode)
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
def right(p: Digit[Node[A]], m: Tree[A], s: List[Node[A]]): Tree[A] = s match {
|
|
744
|
+
case Nil() => m.unconsRightFinger match {
|
|
745
|
+
case TreeIsEmpty() => p.toTree
|
|
746
|
+
case TreeView(a, m2) => deepFinger(p, m2, a.toDigitNode)
|
|
747
|
+
}
|
|
748
|
+
case _ => deepFinger(p, m, s.toDigitNode)
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
def go(tree: Tree[A], index: Int): Split[Node[A], Tree[A]] = tree match {
|
|
752
|
+
case NoFinger() => println("Cannot happen!"); <{ "Cannot happen!" }>
|
|
753
|
+
case SingleFinger(value) => Split(NoFinger(), value, NoFinger())
|
|
754
|
+
case DeepFinger(size, p, m, s) =>
|
|
755
|
+
val psize = p.sizeDeep;
|
|
756
|
+
// It is in the prefix
|
|
757
|
+
if (index < psize) {
|
|
758
|
+
val Split(pp, v, ps) = go(p, index);
|
|
759
|
+
Split(pp.toTree, v, left(ps, m, s))
|
|
760
|
+
} else {
|
|
761
|
+
val msize = psize + m.size
|
|
762
|
+
// It is somewhere in the spine
|
|
763
|
+
if (index < msize) {
|
|
764
|
+
val Split(mp, v, ms) = go(m, index - psize);
|
|
765
|
+
val mpsize = psize + mp.size;
|
|
766
|
+
val Split(vp, w, vs) = go(v.toDigitNode, index - mpsize);
|
|
767
|
+
Split(right(p, mp, vp), w, left(vs, ms, s))
|
|
768
|
+
// It is somewhere in the suffix
|
|
769
|
+
} else {
|
|
770
|
+
val Split(sp, v, ss) = go(s, index - msize)
|
|
771
|
+
Split(right(p, m, sp), v, ss.toTree)
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
if (index < 0) {
|
|
777
|
+
do raise(IndexOutOfBounds(), "...")
|
|
778
|
+
} else if (index >= seq.size) {
|
|
779
|
+
(seq, Empty())
|
|
780
|
+
} else seq match {
|
|
781
|
+
case Empty() => (Empty(), Empty())
|
|
782
|
+
case Single(v) => (Empty(), seq)
|
|
783
|
+
case Deep(size, p, m, s) =>
|
|
784
|
+
val psize = p.size;
|
|
785
|
+
// It is in the prefix
|
|
786
|
+
if (index < psize) {
|
|
787
|
+
val Split(pp, v, ps) = go(p, index);
|
|
788
|
+
(toSeq(pp), left(Cons(v, ps), m, s))
|
|
789
|
+
} else {
|
|
790
|
+
val msize = psize + m.size
|
|
791
|
+
// It is somewhere in the spine
|
|
792
|
+
if (index < msize) {
|
|
793
|
+
val Split(mp, v, ms) = go(m, index - psize);
|
|
794
|
+
val mpsize = psize + mp.size;
|
|
795
|
+
val Split(vp, w, vs) = go(v.toDigit, index - mpsize);
|
|
796
|
+
(right(p, mp, vp), left(Cons(w, vs), ms, s))
|
|
797
|
+
// It is somewhere in the suffix
|
|
798
|
+
} else {
|
|
799
|
+
val Split(sp, v, ss) = go(s, index - msize);
|
|
800
|
+
(right(p, m, sp), Cons(v, ss).toSeq)
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
def insert[A](seq: Seq[A], value: A, index: Int): Seq[A] / Exception[IndexOutOfBounds] =
|
|
808
|
+
splitAt(seq, index) match {
|
|
809
|
+
case (prefix, suffix) => prefix.concat(cons(value, suffix))
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
// Internal conversions
|
|
815
|
+
// --------------------
|
|
816
|
+
|
|
817
|
+
def toTree[A](digit: Digit[Node[A]]): Tree[A] = digit match {
|
|
818
|
+
case One(a) => SingleFinger(a)
|
|
819
|
+
case Two(a, b) => deepFinger(One(a), NoFinger(), One(b))
|
|
820
|
+
case Three(a, b, c) => deepFinger(Two(a, b), NoFinger(), One(c))
|
|
821
|
+
case Four(a, b, c, d) => deepFinger(Three(a, b, c), NoFinger(), One(d))
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
def toTree[A](digit: List[Node[A]]): Tree[A] = digit match {
|
|
825
|
+
case Nil() => NoFinger()
|
|
826
|
+
case Cons(a, Nil()) => SingleFinger(a)
|
|
827
|
+
case Cons(a, Cons(b, Nil())) => deepFinger(One(a), NoFinger(), One(b))
|
|
828
|
+
case Cons(a, Cons(b, Cons(c, Nil()))) => deepFinger(Two(a, b), NoFinger(), One(c))
|
|
829
|
+
case Cons(a, Cons(b, Cons(c, Cons(d, Nil())))) => deepFinger(Three(a, b, c), NoFinger(), One(d))
|
|
830
|
+
case _ => <>
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
def toSeq[A](d: Digit[A]): Seq[A] = d match {
|
|
834
|
+
case One(a) => Single(a)
|
|
835
|
+
case Two(a, b) => Deep(2, One(a), NoFinger(), One(b))
|
|
836
|
+
case Three(a, b, c) => Deep(3, Two(a, b), NoFinger(), One(c))
|
|
837
|
+
case Four(a, b, c, d) => Deep(4, Three(a, b, c), NoFinger(), One(d))
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
def toDigitNode[A](n: Node[A]): Digit[Node[A]] = n match {
|
|
841
|
+
case Node2(_, a, b) => Two(a, b)
|
|
842
|
+
case Node3(_, a, b, c) => Three(a, b, c)
|
|
843
|
+
case _ => <{ "Should not happen" }>
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
def toDigitNode[A](n: List[A]): Digit[A] = n match {
|
|
847
|
+
case Cons(a, Nil()) => One(a)
|
|
848
|
+
case Cons(a, Cons(b, Nil())) => Two(a, b)
|
|
849
|
+
case Cons(a, Cons(b, Cons(c, Nil()))) => Three(a, b, c)
|
|
850
|
+
case Cons(a, Cons(b, Cons(c, Cons(d, Nil())))) => Four(a, b, c, d)
|
|
851
|
+
case _ => <{ "Should not happen" }>
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
def toDigit[A](n: Node[A]): Digit[A] = n match {
|
|
855
|
+
case Leaf2(a, b) => Two(a, b)
|
|
856
|
+
case Leaf3(a, b, c) => Three(a, b, c)
|
|
857
|
+
case _ => <{ "Should not happen" }>
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
def toList[A](digit: Digit[A]): List[A] = digit match {
|
|
861
|
+
case One(a) => Cons(a, Nil())
|
|
862
|
+
case Two(a, b) => Cons(a, Cons(b, Nil()))
|
|
863
|
+
case Three(a, b, c) => Cons(a, Cons(b, Cons(c, Nil())))
|
|
864
|
+
case Four(a, b, c, d) => Cons(a, Cons(b, Cons(c, Cons(d, Nil()))))
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
def map[A, B](seq: Seq[A]) { f: A => B / Control }: Seq[B] = {
|
|
868
|
+
var result: Seq[B] = Empty()
|
|
869
|
+
seq.each { a => result = result.consRight(f(a)) }
|
|
870
|
+
result
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
// TODO iterator interface
|
|
875
|
+
//
|
|
876
|
+
|
|
877
|
+
// interface Iterator[A] {
|
|
878
|
+
// def value(): Option[A]
|
|
879
|
+
// def next(): Unit
|
|
880
|
+
// }
|
|
881
|
+
|
|
882
|
+
// interface Generator[A] {
|
|
883
|
+
// def yield(value: A): Unit
|
|
884
|
+
// }
|
|
885
|
+
|
|
886
|
+
// def iterate[A, R](seq: Seq[A]) { prog: {Iterator[A]} => R }: R = {
|
|
887
|
+
|
|
888
|
+
// var k: Unit => Unit at {} = fun(unit: Unit) { () }
|
|
889
|
+
// var v: Option[A] = None()
|
|
890
|
+
|
|
891
|
+
// try { seq.each { el => do yield(el) } } with Generator[A] {
|
|
892
|
+
// def yield(value) = { v = Some(value); k = box resume }
|
|
893
|
+
// }
|
|
894
|
+
|
|
895
|
+
// new Iterator[A] {
|
|
896
|
+
// def value() = v
|
|
897
|
+
// def next() = (unbox k)(())
|
|
898
|
+
// }
|
|
899
|
+
// }
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
// TODO equality comparison
|
|
903
|
+
//
|