Scala 元组的通用“映射"函数? [英] General 'map' function for Scala tuples?

查看:41
本文介绍了Scala 元组的通用“映射"函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to map the elements of a Scala tuple (or triple, ...) using a single function returning type R. The result should be a tuple (or triple, ...) with elements of type R.

好的,如果元组的元素都来自同一个类型,那么映射就没有问题了:

OK, if the elements of the tuple are from the same type, the mapping is not a problem:

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)

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

But is it also possible to make this solution generic, i.e. to map tuples that contain elements of different types in the same manner?

示例:

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

(Sub1, Sub2) map (_.i)

应该返回

(1,2): (Int, Int)

但是我找不到解决办法让映射函数确定Sub1和Sub2的超类型.我尝试使用类型边界,但我的想法失败了:

But I could not find a solution so that the mapping function determines the super type of Sub1 and Sub2. I tried to use type boundaries, but my idea failed:

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 不支持关于多种类型的类型边界吗?如果是,为什么不呢?

Here X >: B seems to override X >: A. Does Scala not support type boundaries regarding multiple types? If yes, why not?

推荐答案

我认为这就是您要找的:

I think this is what you're looking for:

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)

更实用"的方法是使用 2 个独立的函数:

A more "functional" way to do this would be with 2 separate functions:

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)

这篇关于Scala 元组的通用“映射"函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆