@@ -21,18 +21,22 @@ sealed trait Tuple extends Product:
21
21
inline def toIArray : IArray [Object ] =
22
22
runtime.Tuples .toIArray(this )
23
23
24
- /** Return a copy of `this` tuple with an element appended */
25
- inline def :* [This >: this .type <: Tuple , L ](x : L ): This :* L =
26
- runtime.Tuples .append(x, this ).asInstanceOf [Append [This , L ]]
27
-
28
24
/** Return a new tuple by prepending the element to `this` tuple.
29
25
* This operation is O(this.size)
30
26
*/
31
27
inline def *: [H , This >: this .type <: Tuple ](x : H ): H *: This =
32
28
runtime.Tuples .cons(x, this ).asInstanceOf [H *: This ]
33
29
30
+ /** Return a copy of `this` tuple with an element appended */
31
+ inline def :* [This >: this .type <: Tuple , L ](x : L ): This :* L =
32
+ runtime.Tuples .append(x, this ).asInstanceOf [Append [This , L ]]
33
+
34
+ /** Return the size (or arity) of the tuple */
35
+ inline def size [This >: this .type <: Tuple ]: Size [This ] =
36
+ runtime.Tuples .size(this ).asInstanceOf [Size [This ]]
37
+
34
38
/** Get the i-th element of this tuple.
35
- * Equivalent to productElement but with a precise return type.
39
+ * Equivalent to productElement but with a precise return type.
36
40
*/
37
41
inline def apply [This >: this .type <: Tuple ](n : Int ): Elem [This , n.type ] =
38
42
runtime.Tuples .apply(this , n).asInstanceOf [Elem [This , n.type ]]
@@ -41,19 +45,38 @@ sealed trait Tuple extends Product:
41
45
inline def head [This >: this .type <: Tuple ]: Head [This ] =
42
46
runtime.Tuples .apply(this , 0 ).asInstanceOf [Head [This ]]
43
47
44
- /** Get the initial part of the tuple without its last element */
45
- inline def init [This >: this .type <: Tuple ]: Init [This ] =
46
- runtime.Tuples .init(this ).asInstanceOf [Init [This ]]
48
+ /** Get the tail of this tuple.
49
+ * This operation is O(this.size)
50
+ */
51
+ inline def tail [This >: this .type <: Tuple ]: Tail [This ] =
52
+ runtime.Tuples .tail(this ).asInstanceOf [Tail [This ]]
47
53
48
54
/** Get the last of this tuple */
49
55
inline def last [This >: this .type <: Tuple ]: Last [This ] =
50
56
runtime.Tuples .last(this ).asInstanceOf [Last [This ]]
51
57
52
- /** Get the tail of this tuple.
53
- * This operation is O(this.size)
58
+ /** Get the initial part of the tuple without its last element */
59
+ inline def init [This >: this .type <: Tuple ]: Init [This ] =
60
+ runtime.Tuples .init(this ).asInstanceOf [Init [This ]]
61
+
62
+ /** Given a tuple `(a1, ..., am)`, returns the tuple `(a1, ..., an)` consisting
63
+ * of its first n elements.
54
64
*/
55
- inline def tail [This >: this .type <: Tuple ]: Tail [This ] =
56
- runtime.Tuples .tail(this ).asInstanceOf [Tail [This ]]
65
+ inline def take [This >: this .type <: Tuple ](n : Int ): Take [This , n.type ] =
66
+ runtime.Tuples .take(this , n).asInstanceOf [Take [This , n.type ]]
67
+
68
+ /** Given a tuple `(a1, ..., am)`, returns the tuple `(an+1, ..., am)` consisting
69
+ * all its elements except the first n ones.
70
+ */
71
+ inline def drop [This >: this .type <: Tuple ](n : Int ): Drop [This , n.type ] =
72
+ runtime.Tuples .drop(this , n).asInstanceOf [Drop [This , n.type ]]
73
+
74
+ /** Given a tuple `(a1, ..., am)`, returns a pair of the tuple `(a1, ..., an)`
75
+ * consisting of the first n elements, and the tuple `(an+1, ..., am)` consisting
76
+ * of the remaining elements.
77
+ */
78
+ inline def splitAt [This >: this .type <: Tuple ](n : Int ): Split [This , n.type ] =
79
+ runtime.Tuples .splitAt(this , n).asInstanceOf [Split [This , n.type ]]
57
80
58
81
/** Return a new tuple by concatenating `this` tuple with `that` tuple.
59
82
* This operation is O(this.size + that.size)
@@ -63,10 +86,6 @@ sealed trait Tuple extends Product:
63
86
inline def ++ [This >: this .type <: Tuple ](that : Tuple ): This ++ that.type =
64
87
runtime.Tuples .concat(this , that).asInstanceOf [Concat [This , that.type ]]
65
88
66
- /** Return the size (or arity) of the tuple */
67
- inline def size [This >: this .type <: Tuple ]: Size [This ] =
68
- runtime.Tuples .size(this ).asInstanceOf [Size [This ]]
69
-
70
89
/** Given two tuples, `(a1, ..., an)` and `(a1, ..., an)`, returns a tuple
71
90
* `((a1, b1), ..., (an, bn))`. If the two tuples have different sizes,
72
91
* the extra elements of the larger tuple will be disregarded.
@@ -85,24 +104,11 @@ sealed trait Tuple extends Product:
85
104
inline def map [F [_]](f : [t] => t => F [t]): Map [this .type , F ] =
86
105
runtime.Tuples .map(this , f).asInstanceOf [Map [this .type , F ]]
87
106
88
- /** Given a tuple `(a1, ..., am)`, returns the tuple `(a1, ..., an)` consisting
89
- * of its first n elements.
90
- */
91
- inline def take [This >: this .type <: Tuple ](n : Int ): Take [This , n.type ] =
92
- runtime.Tuples .take(this , n).asInstanceOf [Take [This , n.type ]]
93
-
94
- /** Given a tuple `(a1, ..., am)`, returns the tuple `(an+1, ..., am)` consisting
95
- * all its elements except the first n ones.
96
- */
97
- inline def drop [This >: this .type <: Tuple ](n : Int ): Drop [This , n.type ] =
98
- runtime.Tuples .drop(this , n).asInstanceOf [Drop [This , n.type ]]
99
-
100
- /** Given a tuple `(a1, ..., am)`, returns a pair of the tuple `(a1, ..., an)`
101
- * consisting of the first n elements, and the tuple `(an+1, ..., am)` consisting
102
- * of the remaining elements.
103
- */
104
- inline def splitAt [This >: this .type <: Tuple ](n : Int ): Split [This , n.type ] =
105
- runtime.Tuples .splitAt(this , n).asInstanceOf [Split [This , n.type ]]
107
+ /** A tuple consisting of all elements of this tuple that satisfy the predicate `p`. */
108
+ inline def filter [This >: this .type <: Tuple , P [_ <: Union [This ]] <: Boolean ]
109
+ (p : (x : Union [This ]) => P [x.type ]): Filter [This , P ] =
110
+ val arr = this .toArray.filter(x => p(x.asInstanceOf [Union [This ]]))
111
+ Tuple .fromArray(arr).asInstanceOf [Filter [This , P ]]
106
112
107
113
/** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)`
108
114
* consisting all its elements.
@@ -114,14 +120,16 @@ sealed trait Tuple extends Product:
114
120
inline def reverseOnto [This >: this .type <: Tuple , Acc <: Tuple ](acc : Acc ): ReverseOnto [This , Acc ] =
115
121
(this .reverse ++ acc).asInstanceOf [ReverseOnto [This , Acc ]]
116
122
117
- /** A tuple consisting of all elements of this tuple that satisfy the predicate `p`. */
118
- inline def filter [This >: this .type <: Tuple , P [_ <: Union [This ]] <: Boolean ]
119
- (p : (x : Union [This ]) => P [x.type ]): Filter [This , P ] =
120
- val arr = this .toArray.filter(x => p(x.asInstanceOf [Union [This ]]))
121
- Tuple .fromArray(arr).asInstanceOf [Filter [This , P ]]
122
-
123
123
object Tuple :
124
124
125
+ /** Type of a tuple with an element appended */
126
+ type Append [X <: Tuple , + Y ] <: NonEmptyTuple = X match
127
+ case EmptyTuple => Y *: EmptyTuple
128
+ case x *: xs => x *: Append [xs, Y ]
129
+
130
+ /** An infix shorthand for `Append[X, Y]` */
131
+ infix type :* [X <: Tuple , + Y ] = Append [X , Y ]
132
+
125
133
/** The size of a tuple, represented as a literal constant subtype of Int */
126
134
type Size [X <: Tuple ] <: Int = X match
127
135
case EmptyTuple => 0
@@ -142,15 +150,15 @@ object Tuple:
142
150
type Head [X <: Tuple ] = X match
143
151
case x *: _ => x
144
152
153
+ /** The type of a tuple consisting of all elements of tuple X except the first one */
154
+ type Tail [X <: Tuple ] <: Tuple = X match
155
+ case _ *: xs => xs
156
+
145
157
/** The type of the last element of a tuple */
146
158
type Last [X <: Tuple ] = X match
147
159
case x *: EmptyTuple => x
148
160
case _ *: xs => Last [xs]
149
161
150
- /** The type of a tuple consisting of all elements of tuple X except the first one */
151
- type Tail [X <: Tuple ] <: Tuple = X match
152
- case _ *: xs => xs
153
-
154
162
/** The type of the initial part of a tuple without its last element */
155
163
type Init [X <: Tuple ] <: Tuple = X match
156
164
case _ *: EmptyTuple => EmptyTuple
@@ -177,14 +185,6 @@ object Tuple:
177
185
/** The pair type `(Take(X, N), Drop[X, N]). */
178
186
type Split [X <: Tuple , N <: Int ] = (Take [X , N ], Drop [X , N ])
179
187
180
- /** Type of a tuple with an element appended */
181
- type Append [X <: Tuple , + Y ] <: NonEmptyTuple = X match
182
- case EmptyTuple => Y *: EmptyTuple
183
- case x *: xs => x *: Append [xs, Y ]
184
-
185
- /** An infix shorthand for `Append[X, Y]` */
186
- infix type :* [X <: Tuple , + Y ] = Append [X , Y ]
187
-
188
188
/** Type of the concatenation of two tuples `X` and `Y` */
189
189
// Can be covariant in `Y` since it never appears as a match type scrutinee.
190
190
type Concat [X <: Tuple , + Y <: Tuple ] <: Tuple = X match
@@ -194,18 +194,25 @@ object Tuple:
194
194
/** An infix shorthand for `Concat[X, Y]` */
195
195
infix type ++ [X <: Tuple , + Y <: Tuple ] = Concat [X , Y ]
196
196
197
- /** The index of `Y` in tuple `X` as a literal constant Int,
198
- * or `Size[X]` if `Y` is disjoint from all element types in `X`.
197
+ /** The type of the tuple consisting of all element values of
198
+ * tuple `X` zipped with corresponding elements of tuple `Y`.
199
+ * If the two tuples have different sizes,
200
+ * the extra elements of the larger tuple will be disregarded.
201
+ * For example, if
202
+ * ```
203
+ * X = (S1, ..., Si)
204
+ * Y = (T1, ..., Tj) where j >= i
205
+ * ```
206
+ * then
207
+ * ```
208
+ * Zip[X, Y] = ((S1, T1), ..., (Si, Ti))
209
+ * ```
210
+ * @syntax markdown
199
211
*/
200
- type IndexOf [X <: Tuple , Y ] <: Int = X match
201
- case Y *: _ => 0
202
- case _ *: xs => S [IndexOf [xs, Y ]]
203
- case EmptyTuple => 0
204
-
205
- /** Fold a tuple `(T1, ..., Tn)` into `F[T1, F[... F[Tn, Z]...]]]` */
206
- type Fold [X <: Tuple , Z , F [_, _]] = X match
207
- case EmptyTuple => Z
208
- case x *: xs => F [x, Fold [xs, Z , F ]]
212
+ type Zip [X <: Tuple , Y <: Tuple ] <: Tuple = (X , Y ) match
213
+ case (x *: xs, y *: ys) => (x, y) *: Zip [xs, ys]
214
+ case (EmptyTuple , _) => EmptyTuple
215
+ case (_, EmptyTuple ) => EmptyTuple
209
216
210
217
/** The type of tuple `X` mapped with the type-level function `F`.
211
218
* If `X = (T1, ..., Ti)` then `Map[X, F] = `(F[T1], ..., F[Ti])`.
@@ -214,6 +221,18 @@ object Tuple:
214
221
case EmptyTuple => EmptyTuple
215
222
case x *: xs => F [x] *: Map [xs, F ]
216
223
224
+ /** Converts a tuple `(F[T1], ..., F[Tn])` to `(T1, ... Tn)` */
225
+ type InverseMap [X <: Tuple , F [_]] <: Tuple = X match
226
+ case F [x] *: xs => x *: InverseMap [xs, F ]
227
+ case EmptyTuple => EmptyTuple
228
+
229
+ /** Implicit evidence. IsMappedBy[F][X] is present in the implicit scope iff
230
+ * X is a tuple for which each element's type is constructed via `F`. E.g.
231
+ * (F[A1], ..., F[An]), but not `(F[A1], B2, ..., F[An])` where B2 does not
232
+ * have the shape of `F[A]`.
233
+ */
234
+ type IsMappedBy [F [_]] = [X <: Tuple ] =>> X =:= Map [InverseMap [X , F ], F ]
235
+
217
236
/** The type of tuple `X` flat-mapped with the type-level function `F`.
218
237
* If `X = (T1, ..., Ti)` then `FlatMap[X, F] = `F[T1] ++ ... ++ F[Ti]`
219
238
*/
@@ -241,44 +260,6 @@ object Tuple:
241
260
case true => x *: Filter [xs, P ]
242
261
case false => Filter [xs, P ]
243
262
244
- /** A tuple consisting of those indices `N` of tuple `X` where the predicate `P`
245
- * is true for `Elem[X, N]`. Indices are type level values <: Int.
246
- */
247
- type IndicesWhere [X <: Tuple , P [_ <: Union [X ]] <: Boolean ] =
248
- helpers.IndicesWhereHelper [X , P , 0 ]
249
-
250
- /** The type of the tuple consisting of all element values of
251
- * tuple `X` zipped with corresponding elements of tuple `Y`.
252
- * If the two tuples have different sizes,
253
- * the extra elements of the larger tuple will be disregarded.
254
- * For example, if
255
- * ```
256
- * X = (S1, ..., Si)
257
- * Y = (T1, ..., Tj) where j >= i
258
- * ```
259
- * then
260
- * ```
261
- * Zip[X, Y] = ((S1, T1), ..., (Si, Ti))
262
- * ```
263
- * @syntax markdown
264
- */
265
- type Zip [X <: Tuple , Y <: Tuple ] <: Tuple = (X , Y ) match
266
- case (x *: xs, y *: ys) => (x, y) *: Zip [xs, ys]
267
- case (EmptyTuple , _) => EmptyTuple
268
- case (_, EmptyTuple ) => EmptyTuple
269
-
270
- /** Converts a tuple `(F[T1], ..., F[Tn])` to `(T1, ... Tn)` */
271
- type InverseMap [X <: Tuple , F [_]] <: Tuple = X match
272
- case F [x] *: xs => x *: InverseMap [xs, F ]
273
- case EmptyTuple => EmptyTuple
274
-
275
- /** Implicit evidence. IsMappedBy[F][X] is present in the implicit scope iff
276
- * X is a tuple for which each element's type is constructed via `F`. E.g.
277
- * (F[A1], ..., F[An]), but not `(F[A1], B2, ..., F[An])` where B2 does not
278
- * have the shape of `F[A]`.
279
- */
280
- type IsMappedBy [F [_]] = [X <: Tuple ] =>> X =:= Map [InverseMap [X , F ], F ]
281
-
282
263
/** A tuple with the elements of tuple `X` in reversed order */
283
264
type Reverse [X <: Tuple ] = ReverseOnto [X , EmptyTuple ]
284
265
@@ -287,11 +268,30 @@ object Tuple:
287
268
case x *: xs => ReverseOnto [xs, x *: Acc ]
288
269
case EmptyTuple => Acc
289
270
271
+ /** Fold a tuple `(T1, ..., Tn)` into `F[T1, F[... F[Tn, Z]...]]]` */
272
+ type Fold [X <: Tuple , Z , F [_, _]] = X match
273
+ case EmptyTuple => Z
274
+ case x *: xs => F [x, Fold [xs, Z , F ]]
275
+
290
276
/** Given a tuple `(T1, ..., Tn)`, returns a union of its
291
277
* member types: `T1 | ... | Tn`. Returns `Nothing` if the tuple is empty.
292
278
*/
293
279
type Union [T <: Tuple ] = Fold [T , Nothing , [x, y] =>> x | y]
294
280
281
+ /** The index of `Y` in tuple `X` as a literal constant Int,
282
+ * or `Size[X]` if `Y` is disjoint from all element types in `X`.
283
+ */
284
+ type IndexOf [X <: Tuple , Y ] <: Int = X match
285
+ case Y *: _ => 0
286
+ case _ *: xs => S [IndexOf [xs, Y ]]
287
+ case EmptyTuple => 0
288
+
289
+ /** A tuple consisting of those indices `N` of tuple `X` where the predicate `P`
290
+ * is true for `Elem[X, N]`. Indices are type level values <: Int.
291
+ */
292
+ type IndicesWhere [X <: Tuple , P [_ <: Union [X ]] <: Boolean ] =
293
+ helpers.IndicesWhereHelper [X , P , 0 ]
294
+
295
295
/** A type level Boolean indicating whether the tuple `X` has an element
296
296
* that matches `Y`.
297
297
* @pre The elements of `X` are assumed to be singleton types
0 commit comments