Skip to content

Commit bb598f5

Browse files
Try other Tuple map method
1 parent 5850d2d commit bb598f5

File tree

6 files changed

+35
-19
lines changed

6 files changed

+35
-19
lines changed

library/src/scala/Tuple.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ sealed trait Tuple extends Product {
5656
* If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known
5757
* to be the cons type.
5858
*/
59-
inline def map[F[_]](f: [t] => t => F[t]): Map[this.type, F] =
59+
inline def map[F[_ <: Union[this.type]]](f: (t: Union[this.type]) => F[t.type]): Map[this.type, F] =
6060
runtime.Tuples.map(this, f).asInstanceOf[Map[this.type, F]]
6161

6262
/** Given a tuple `(a1, ..., am)`, returns the tuple `(a1, ..., an)` consisting

library/src/scala/runtime/Tuples.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,11 @@ object Tuples {
598598
)
599599
}
600600

601-
def map[F[_]](self: Tuple, f: [t] => t => F[t]): Tuple = self match {
601+
def map[T <: Tuple, F[_ <: Tuple.Union[T]]](self: T, f: (t: Tuple.Union[T]) => F[t.type]): Tuple = self match {
602602
case EmptyTuple => self
603-
case _ => fromIArray(self.productIterator.map(f(_).asInstanceOf[Object]).toArray.asInstanceOf[IArray[Object]]) // TODO use toIArray
603+
case _ =>
604+
val iterator = self.productIterator.asInstanceOf[Iterator[Tuple.Union[T]]]
605+
fromIArray(iterator.map(f(_)).toArray.asInstanceOf[IArray[Object]]) // TODO use toIArray
604606
}
605607

606608
def take(self: Tuple, n: Int): Tuple = {

tests/pos/i14351.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
val p: (Option[Int], Option[String]) = (1,"foo").map([T] => (x: T) => Option.apply[T](x))
1+
val p: (Option[Int], Option[String]) = (1,"foo").map(Option(_))

tests/pos/i8300.scala

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,5 @@ type Bar[X] = X match {
66
}
77

88
object Test:
9-
(Set(1, 2, 3), List("a", "b")).map(
10-
[A] =>
11-
(a: A) =>
12-
a match {
13-
case it: Iterable[x] => it.map(Tuple1(_)).asInstanceOf[Bar[A]]
14-
}
15-
)
9+
(Set(1, 2, 3), List("a", "b")).map:
10+
a => a.map(Tuple1(_)).asInstanceOf[Bar[a.type]]

tests/run/tuple-map.scala

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,35 @@ object Test extends App {
44
val tuple: Tuple = ("1", "2", "3", "4", "5")
55
val tupleXXL: Tuple = ("11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35")
66

7-
type Id[X] = X
8-
val f: [t] => t => Id[t] = [t] => (x: t) => {
7+
type F[X] = String
8+
val f: (t: Any) => F[t.type] = x => {
99
val str = x.asInstanceOf[String]
10-
str.updated(0, (str(0) + 1).toChar).asInstanceOf[t]
10+
str.updated(0, (str(0) + 1).toChar)
1111
}
1212

1313
// Test all possible combinations of making
1414
println(emptyTuple.map(f))
1515
println(tuple.map(f))
1616
println(tupleXXL.map(f))
17+
18+
// NOTE F is needed in ascription of f above for inference of .map
19+
def alternative: Unit =
20+
val f: (t: Any) => String = x => {
21+
val str = x.asInstanceOf[String]
22+
str.updated(0, (str(0) + 1).toChar)
23+
}
24+
println(emptyTuple.map[F](f))
25+
println(tuple.map[F](f))
26+
println(tupleXXL.map[F](f))
27+
28+
// Given the body of f, the following is more likely to occur in practice:
29+
def withoutWidening: Unit =
30+
val emptyTuple = Tuple()
31+
val tuple = ("1", "2", "3", "4", "5")
32+
val tupleXXL = ("11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35")
33+
val f: (s: String) => F[s.type] = str => str.updated(0, (str(0) + 1).toChar)
34+
println(emptyTuple.map(f))
35+
println(tuple.map(f))
36+
println(tupleXXL.map(f))
37+
1738
}

tests/run/tuple-ops.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ val r5: Unit = a.zip(d)
1313
// Map
1414
case class Foo[X](x: X)
1515

16-
val r6: (Int, Int, Int) = a.map[[t] =>> Int]([t] => (x: t) => x match {
17-
case x: Int => x * x
18-
case _ => ???
19-
})
16+
val r6: (Int, Int, Int) = a.map[[t] =>> Int](x => x * x)
2017

2118
val r7: ((1, Foo[1]), (2, Foo[2]), (3, Foo[3])) =
22-
a.map[[t] =>> (t, Foo[t])]( [t] => (x: t) => (x, Foo(x)) )
19+
a.map[[t] =>> (t, Foo[t])](x => (x, Foo(x)))
20+
// NOTE might not need give type param if had `precise` modifier for x
2321

2422
// More Zip
2523
val t1: Int *: Long *: Tuple = (1, 2l, 100, 200)

0 commit comments

Comments
 (0)