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