@@ -9,35 +9,42 @@ sealed trait Tuple extends Product {
9
9
import Tuple .*
10
10
11
11
/** Create a copy of this tuple as an Array */
12
+ private [Tuple ]
12
13
inline def toArray : Array [Object ] =
13
14
runtime.Tuples .toArray(this )
14
15
15
16
/** Create a copy of this tuple as a List */
17
+ private [Tuple ]
16
18
inline def toList : List [Union [this .type ]] =
17
19
this .productIterator.toList
18
20
.asInstanceOf [List [Union [this .type ]]]
19
21
20
22
/** Create a copy of this tuple as an IArray */
23
+ private [Tuple ]
21
24
inline def toIArray : IArray [Object ] =
22
25
runtime.Tuples .toIArray(this )
23
26
24
27
/** Return a copy of `this` tuple with an element appended */
28
+ private [Tuple ]
25
29
inline def :* [This >: this .type <: Tuple , L ] (x : L ): Append [This , L ] =
26
30
runtime.Tuples .append(x, this ).asInstanceOf [Append [This , L ]]
27
31
28
32
/** Return a new tuple by prepending the element to `this` tuple.
29
33
* This operation is O(this.size)
30
34
*/
35
+ private [Tuple ]
31
36
inline def *: [H , This >: this .type <: Tuple ] (x : H ): H *: This =
32
37
runtime.Tuples .cons(x, this ).asInstanceOf [H *: This ]
33
38
34
39
/** Return a new tuple by concatenating `this` tuple with `that` tuple.
35
40
* This operation is O(this.size + that.size)
36
41
*/
42
+ private [Tuple ]
37
43
inline def ++ [This >: this .type <: Tuple ](that : Tuple ): Concat [This , that.type ] =
38
44
runtime.Tuples .concat(this , that).asInstanceOf [Concat [This , that.type ]]
39
45
40
46
/** Return the size (or arity) of the tuple */
47
+ private [Tuple ]
41
48
inline def size [This >: this .type <: Tuple ]: Size [This ] =
42
49
runtime.Tuples .size(this ).asInstanceOf [Size [This ]]
43
50
@@ -48,6 +55,7 @@ sealed trait Tuple extends Product {
48
55
* tuple types has a `EmptyTuple` tail. Otherwise the result type is
49
56
* `(A1, B1) *: ... *: (Ai, Bi) *: Tuple`
50
57
*/
58
+ private [Tuple ]
51
59
inline def zip [This >: this .type <: Tuple , T2 <: Tuple ](t2 : T2 ): Zip [This , T2 ] =
52
60
runtime.Tuples .zip(this , t2).asInstanceOf [Zip [This , T2 ]]
53
61
@@ -56,39 +64,140 @@ sealed trait Tuple extends Product {
56
64
* If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known
57
65
* to be the cons type.
58
66
*/
67
+ private [Tuple ]
59
68
inline def map [F [_]](f : [t] => t => F [t]): Map [this .type , F ] =
60
69
runtime.Tuples .map(this , f).asInstanceOf [Map [this .type , F ]]
61
70
62
71
/** Given a tuple `(a1, ..., am)`, returns the tuple `(a1, ..., an)` consisting
63
72
* of its first n elements.
64
73
*/
74
+ private [Tuple ]
65
75
inline def take [This >: this .type <: Tuple ](n : Int ): Take [This , n.type ] =
66
76
runtime.Tuples .take(this , n).asInstanceOf [Take [This , n.type ]]
67
77
68
78
69
79
/** Given a tuple `(a1, ..., am)`, returns the tuple `(an+1, ..., am)` consisting
70
80
* all its elements except the first n ones.
71
81
*/
82
+ private [Tuple ]
72
83
inline def drop [This >: this .type <: Tuple ](n : Int ): Drop [This , n.type ] =
73
84
runtime.Tuples .drop(this , n).asInstanceOf [Drop [This , n.type ]]
74
85
75
86
/** Given a tuple `(a1, ..., am)`, returns a pair of the tuple `(a1, ..., an)`
76
87
* consisting of the first n elements, and the tuple `(an+1, ..., am)` consisting
77
88
* of the remaining elements.
78
89
*/
90
+ private [Tuple ]
79
91
inline def splitAt [This >: this .type <: Tuple ](n : Int ): Split [This , n.type ] =
80
92
runtime.Tuples .splitAt(this , n).asInstanceOf [Split [This , n.type ]]
81
-
82
- /** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)`
83
- * consisting all its elements.
84
- */
85
- @ experimental
86
- inline def reverse [This >: this .type <: Tuple ]: Reverse [This ] =
87
- runtime.Tuples .reverse(this ).asInstanceOf [Reverse [This ]]
88
93
}
89
94
90
95
object Tuple {
91
96
97
+ // TODO should it be `extension [H](x: H) def *:(tail: Tuple): H *: tuple.type` ?
98
+ extension [H , Tail <: Tuple ](x : H )
99
+ /** Return a new tuple by prepending the element to `tail` tuple.
100
+ * This operation is O(tail.size)
101
+ */
102
+ def *: (tail : Tail ): H *: Tail = runtime.Tuples .cons(x, tail).asInstanceOf [H *: Tail ]
103
+
104
+ extension [This <: Tuple ](tuple : This )
105
+ /** Get the head of this tuple */
106
+ def head : Head [This ] & Head [tuple.type ] =
107
+ runtime.Tuples .apply(tuple, 0 ).asInstanceOf [Head [This ] & Head [tuple.type ]]
108
+
109
+ /** Get the tail of this tuple.
110
+ * This operation is O(tuple.size)
111
+ */
112
+ def tail : Tail [This ] & Tail [tuple.type ] =
113
+ runtime.Tuples .tail(tuple).asInstanceOf [Tail [This ] & Tail [tuple.type ]]
114
+
115
+ /** Return the size (or arity) of the tuple */
116
+ def size : Size [This ] & Size [tuple.type ] =
117
+ runtime.Tuples .size(tuple).asInstanceOf [Size [This ] & Size [tuple.type ]]
118
+
119
+ /** Get the i-th element of this tuple.
120
+ * Equivalent to productElement but with a precise return type.
121
+ */
122
+ def apply (n : Int ): Elem [This , n.type ] & Elem [tuple.type , n.type ] =
123
+ runtime.Tuples .apply(tuple, n).asInstanceOf [Elem [This , n.type ] & Elem [tuple.type , n.type ]]
124
+
125
+ /** Get the initial part of the tuple without its last element */
126
+ def init : Init [This ] & Init [tuple.type ] =
127
+ runtime.Tuples .init(tuple).asInstanceOf [Init [This ] & Init [tuple.type ]]
128
+
129
+ /** Get the last of this tuple */
130
+ def last : Last [This ] & Last [tuple.type ] =
131
+ runtime.Tuples .last(tuple).asInstanceOf [Last [This ] & Last [tuple.type ]]
132
+
133
+ /** Return a copy of `tuple` with an element appended */
134
+ def :* [X ] (x : X ): Append [This , X ] & Append [tuple.type , X ] =
135
+ runtime.Tuples .append(x, tuple).asInstanceOf [Append [This , X ] & Append [tuple.type , X ]]
136
+
137
+ /** Return a new tuple by concatenating `this` tuple with `that` tuple.
138
+ * This operation is O(this.size + that.size)
139
+ */
140
+ def ++ (that : Tuple ): Concat [This , that.type ] & Concat [tuple.type , that.type ] =
141
+ runtime.Tuples .concat(tuple, that).asInstanceOf [Concat [This , that.type ] & Concat [tuple.type , that.type ]]
142
+
143
+ /** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)`
144
+ * consisting all its elements.
145
+ */
146
+ @ experimental
147
+ def reverse : Reverse [This ] & Reverse [tuple.type ] =
148
+ runtime.Tuples .reverse(tuple).asInstanceOf [Reverse [This ] & Reverse [tuple.type ]]
149
+
150
+ /** Given two tuples, `(a1, ..., an)` and `(a1, ..., an)`, returns a tuple
151
+ * `((a1, b1), ..., (an, bn))`. If the two tuples have different sizes,
152
+ * the extra elements of the larger tuple will be disregarded.
153
+ * The result is typed as `((A1, B1), ..., (An, Bn))` if at least one of the
154
+ * tuple types has a `EmptyTuple` tail. Otherwise the result type is
155
+ * `(A1, B1) *: ... *: (Ai, Bi) *: Tuple`
156
+ */
157
+ // TODO change signature? def zip[That <: Tuple](that: That): Zip[This, tuple.type] & Zip[tuple.type, tuple.type] =
158
+ def zip [That <: Tuple ](that : That ): Zip [This , That ] & Zip [tuple.type , That ] =
159
+ runtime.Tuples .zip(tuple, that).asInstanceOf [Zip [This , That ] & Zip [tuple.type , That ]]
160
+
161
+ /** Called on a tuple `(a1, ..., an)`, returns a new tuple `(f(a1), ..., f(an))`.
162
+ * The result is typed as `(F[A1], ..., F[An])` if the tuple type is fully known.
163
+ * If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known
164
+ * to be the cons type.
165
+ */
166
+ def map [F [_]](f : [t] => t => F [t]): Map [This , F ] & Map [tuple.type , F ] =
167
+ runtime.Tuples .map(tuple, f).asInstanceOf [Map [This , F ] & Map [tuple.type , F ]]
168
+
169
+ /** Given a tuple `(a1, ..., am)`, returns the tuple `(a1, ..., an)` consisting
170
+ * of its first n elements.
171
+ */
172
+ def take (n : Int ): Take [This , n.type ] & Take [tuple.type , n.type ] =
173
+ runtime.Tuples .take(tuple, n).asInstanceOf [Take [This , n.type ] & Take [tuple.type , n.type ]]
174
+
175
+ /** Given a tuple `(a1, ..., am)`, returns the tuple `(an+1, ..., am)` consisting
176
+ * all its elements except the first n ones.
177
+ */
178
+ def drop (n : Int ): Drop [This , n.type ] & Take [tuple.type , n.type ] =
179
+ runtime.Tuples .drop(tuple, n).asInstanceOf [Drop [This , n.type ] & Take [tuple.type , n.type ]]
180
+
181
+ /** Given a tuple `(a1, ..., am)`, returns a pair of the tuple `(a1, ..., an)`
182
+ * consisting of the first n elements, and the tuple `(an+1, ..., am)` consisting
183
+ * of the remaining elements.
184
+ */
185
+ def splitAt (n : Int ): Split [This , n.type ] & Split [tuple.type , n.type ] =
186
+ runtime.Tuples .splitAt(tuple, n).asInstanceOf [Split [This , n.type ] & Split [tuple.type , n.type ]]
187
+
188
+ /** Create a copy of this tuple as a List */
189
+ def toList : List [Union [This ]] & List [Union [tuple.type ]] =
190
+ tuple.productIterator.toList.asInstanceOf [List [Union [This ]] & List [Union [tuple.type ]]]
191
+ end extension
192
+
193
+ extension (tuple : Tuple )
194
+ /** Create a copy of this tuple as an Array */
195
+ def toArray : Array [AnyRef ] = runtime.Tuples .toArray(tuple)
196
+
197
+ /** Create a copy of this tuple as an IArray */
198
+ def toIArray : IArray [AnyRef ] = runtime.Tuples .toIArray(tuple)
199
+ end extension
200
+
92
201
/** Type of a tuple with an element appended */
93
202
type Append [X <: Tuple , Y ] <: NonEmptyTuple = X match {
94
203
case EmptyTuple => Y *: EmptyTuple
@@ -98,24 +207,27 @@ object Tuple {
98
207
/** Type of the head of a tuple */
99
208
type Head [X <: Tuple ] = X match {
100
209
case x *: _ => x
210
+ case EmptyTuple => Nothing
101
211
}
102
212
103
213
/** Type of the initial part of the tuple without its last element */
104
214
type Init [X <: Tuple ] <: Tuple = X match {
105
215
case _ *: EmptyTuple => EmptyTuple
106
- case x *: xs =>
107
- x *: Init [xs]
216
+ case x *: xs => x *: Init [xs]
217
+ case EmptyTuple => Nothing
108
218
}
109
219
110
220
/** Type of the tail of a tuple */
111
221
type Tail [X <: Tuple ] <: Tuple = X match {
112
222
case _ *: xs => xs
223
+ case EmptyTuple => Nothing
113
224
}
114
225
115
226
/** Type of the last element of a tuple */
116
227
type Last [X <: Tuple ] = X match {
117
228
case x *: EmptyTuple => x
118
229
case _ *: xs => Last [xs]
230
+ case EmptyTuple => Nothing
119
231
}
120
232
121
233
/** Type of the concatenation of two tuples */
@@ -180,6 +292,7 @@ object Tuple {
180
292
* returns the tuple type `(A1, B1) *: ... *: (An, Bn) *: Ct`
181
293
* where `Ct` is `EmptyTuple` if `At` or `Bt` is `EmptyTuple`, otherwise `Ct` is `Tuple`.
182
294
*/
295
+ // TODO should zip be covariant? type Zip[T1 <: Tuple, +T2 <: Tuple] <: Tuple = ...
183
296
type Zip [T1 <: Tuple , T2 <: Tuple ] <: Tuple = (T1 , T2 ) match {
184
297
case (h1 *: t1, h2 *: t2) => (h1, h2) *: Zip [t1, t2]
185
298
case (EmptyTuple , _) => EmptyTuple
@@ -294,24 +407,29 @@ sealed trait NonEmptyTuple extends Tuple {
294
407
/** Get the i-th element of this tuple.
295
408
* Equivalent to productElement but with a precise return type.
296
409
*/
410
+ private [NonEmptyTuple ]
297
411
inline def apply [This >: this .type <: NonEmptyTuple ](n : Int ): Elem [This , n.type ] =
298
412
runtime.Tuples .apply(this , n).asInstanceOf [Elem [This , n.type ]]
299
413
300
414
/** Get the head of this tuple */
415
+ private [NonEmptyTuple ]
301
416
inline def head [This >: this .type <: NonEmptyTuple ]: Head [This ] =
302
417
runtime.Tuples .apply(this , 0 ).asInstanceOf [Head [This ]]
303
418
304
419
/** Get the initial part of the tuple without its last element */
420
+ private [NonEmptyTuple ]
305
421
inline def init [This >: this .type <: NonEmptyTuple ]: Init [This ] =
306
422
runtime.Tuples .init(this ).asInstanceOf [Init [This ]]
307
423
308
424
/** Get the last of this tuple */
425
+ private [NonEmptyTuple ]
309
426
inline def last [This >: this .type <: NonEmptyTuple ]: Last [This ] =
310
427
runtime.Tuples .last(this ).asInstanceOf [Last [This ]]
311
428
312
429
/** Get the tail of this tuple.
313
430
* This operation is O(this.size)
314
431
*/
432
+ private [NonEmptyTuple ]
315
433
inline def tail [This >: this .type <: NonEmptyTuple ]: Tail [This ] =
316
434
runtime.Tuples .tail(this ).asInstanceOf [Tail [This ]]
317
435
}
0 commit comments