Scala元组的一般'map'功能?

Ste*_*lis 9 scala tuples contravariance superclass

我想使用返回类型R的单个函数映射Scala元组(或三元组......)的元素.结果应该是元组类型为R的元组(或三元组......).

好的,如果元组的元素来自同一类型,则映射不是问题:

scala> implicit def t2mapper[A](t: (A,A)) = new { def map[R](f: A => R) = (f(t._1),f(t._2)) }
t2mapper: [A](t: (A, A))java.lang.Object{def map[R](f: (A) => R): (R, R)}

scala> (1,2) map (_ + 1)
res0: (Int, Int) = (2,3)
Run Code Online (Sandbox Code Playgroud)

但是,是否也可以使这个解决方案通用,即以相同的方式映射包含不同类型元素的元组?

例:

class Super(i: Int)
object Sub1 extends Super(1)
object Sub2 extends Super(2)

(Sub1, Sub2) map (_.i)
Run Code Online (Sandbox Code Playgroud)

应该回来

(1,2): (Int, Int)
Run Code Online (Sandbox Code Playgroud)

但我找不到解决方案,以便映射函数确定Sub1和Sub2的超类型.我试图使用类型边界,但我的想法失败了:

scala> implicit def t2mapper[A,B](t: (A,B)) = new { def map[X >: A, X >: B, R](f: X => R) = (f(t._1),f(t._2)) }
<console>:8: error: X is already defined as type X
       implicit def t2mapper[A,B](t: (A,B)) = new { def map[X >: A, X >: B, R](f: X => R) = (f(t._1),f(t._2)) }
                                                                    ^
<console>:8: error: type mismatch;
 found   : A
 required: X
 Note: implicit method t2mapper is not applicable here because it comes after the application point and it lacks an explicit result type
       implicit def t2mapper[A,B](t: (A,B)) = new { def map[X >: A, X >: B, R](f: X => R) = (f(t._1),f(t._2)) }
Run Code Online (Sandbox Code Playgroud)

X >: B似乎是覆盖X >: A.Scala不支持多种类型的类型边界吗?如果是的话,为什么不呢?

Tom*_*ett 11

我想这就是你要找的东西:

implicit def t2mapper[X, A <: X, B <: X](t: (A,B)) = new {
  def map[R](f: X => R) = (f(t._1), f(t._2))
}

scala> (Sub1, Sub2) map (_.i)                             
res6: (Int, Int) = (1,2)
Run Code Online (Sandbox Code Playgroud)

一个更"实用"的方法是使用2个独立的功能:

implicit def t2mapper[A, B](t: (A, B)) = new { 
  def map[R](f: A => R, g: B => R) = (f(t._1), g(t._2)) 
}       

scala> (1, "hello") map (_ + 1, _.length)                                         
res1: (Int, Int) = (2,5)
Run Code Online (Sandbox Code Playgroud)


Deb*_*ski 5

I\xe2\x80\x99m 不是 scala 类型的天才,但也许这有效:

\n\n
implicit def t2mapper[X, A<:X, B<:X](t: (A,B)) = new { def map[A, B, R](f: X => R) = (f(t._1),f(t._2)) }\n
Run Code Online (Sandbox Code Playgroud)\n