タイプRを返す単一の関数を使用してScalaタプル(またはトリプル、...)の要素をマップしたいと思います。結果は、タイプRの要素を持つタプル(またはトリプル、...)になります。
OK、タプルの要素が同じタイプのものである場合、マッピングは問題ではありません。
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)
しかし、このソリューションを一般的にすること、つまり、同じ方法で異なるタイプの要素を含むタプルをマップすることも可能ですか?
例:
class Super(i: Int)
object Sub1 extends Super(1)
object Sub2 extends Super(2)
(Sub1, Sub2) map (_.i)
戻る必要があります
(1,2): (Int, Int)
しかし、マッピング関数が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)) }
ここでX >: B
オーバーライドするようX >: A
です。Scalaは複数のタイプに関するタイプ境界をサポートしていませんか?はいの場合、なぜですか?