@@ -33,6 +33,23 @@ sealed trait Tuple extends Any {
33
33
inline def size [This >: this .type <: Tuple ]: Size [This ] =
34
34
DynamicTuple .dynamicSize(this )
35
35
36
+ /** Given two tuples, `(a1, ..., an)` and `(a1, ..., an)`, returns a tuple
37
+ * `((a1, b1), ..., (an, bn))`. If the two tuples have different sizes,
38
+ * the extra elements of the larger tuple will be disregarded.
39
+ * The result is typed as `((A1, B1), ..., (An, Bn))` if at least one of the
40
+ * tuple types has a `Unit` tail. Otherwise the result type is
41
+ * `(A1, B1) *: ... *: (Ai, Bi) *: Tuple`
42
+ */
43
+ inline def zip [This >: this .type <: Tuple , T2 <: Tuple ](t2 : T2 ): Zip [This , T2 ] =
44
+ DynamicTuple .dynamicZip(this , t2)
45
+
46
+ /** Called on a tuple `(a1, ..., an)`, returns a new tuple `(f(a1), ..., f(an))`.
47
+ * The result is typed as `(F[A1], ..., F[An])` if the tuple type is fully known.
48
+ * If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known
49
+ * to be the cons type.
50
+ */
51
+ inline def map [F [_]](f : [t] => t => F [t]): Map [this .type , F ] =
52
+ DynamicTuple .dynamicMap(this , f)
36
53
}
37
54
38
55
object Tuple {
@@ -74,6 +91,18 @@ object Tuple {
74
91
case h *: t => F [h] *: Map [t, F ]
75
92
}
76
93
94
+ /** Given two tuples, `A1 *: ... *: An * At` and `B1 *: ... *: Bn *: Bt`
95
+ * where at least one of `At` or `Bt` is `Unit` or `Tuple`,
96
+ * returns the tuple type `(A1, B1) *: ... *: (An, Bn) *: Ct`
97
+ * where `Ct` is `Unit` if `At` or `Bt` is `Unit`, otherwise `Ct` is `Tuple`.
98
+ */
99
+ type Zip [T1 <: Tuple , T2 <: Tuple ] <: Tuple = (T1 , T2 ) match {
100
+ case (h1 *: t1, h2 *: t2) => (h1, h2) *: Zip [t1, t2]
101
+ case (Unit , _) => Unit
102
+ case (_, Unit ) => Unit
103
+ case _ => Tuple
104
+ }
105
+
77
106
/** Convert an array into a tuple of unknown arity and types */
78
107
def fromArray [T ](xs : Array [T ]): Tuple = {
79
108
val xs2 = xs match {
@@ -98,6 +127,8 @@ object Tuple {
98
127
def fromProduct (product : Product ): Tuple =
99
128
runtime.DynamicTuple .dynamicFromProduct[Tuple ](product)
100
129
130
+ def fromProductTyped [P <: Product ](p : P ) given (m : scala.deriving.Mirror .ProductOf [P ]): m.MirroredElemTypes =
131
+ Tuple .fromArray(p.productIterator.toArray).asInstanceOf [m.MirroredElemTypes ] // TODO use toIArray of Object to avoid double/triple array copy
101
132
}
102
133
103
134
/** Tuple of arbitrary non-zero arity */
0 commit comments