@@ -33,6 +33,23 @@ sealed trait Tuple extends Any {
3333 inline def size [This >: this .type <: Tuple ]: Size [This ] =
3434 DynamicTuple .dynamicSize(this )
3535
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)
3653}
3754
3855object Tuple {
@@ -74,6 +91,18 @@ object Tuple {
7491 case h *: t => F [h] *: Map [t, F ]
7592 }
7693
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+
77106 /** Convert an array into a tuple of unknown arity and types */
78107 def fromArray [T ](xs : Array [T ]): Tuple = {
79108 val xs2 = xs match {
@@ -98,6 +127,8 @@ object Tuple {
98127 def fromProduct (product : Product ): Tuple =
99128 runtime.DynamicTuple .dynamicFromProduct[Tuple ](product)
100129
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
101132}
102133
103134/** Tuple of arbitrary non-zero arity */
0 commit comments