scala map / type instantiation

时间:2012-04-10 02:44:36

标签: scala generics

有人可以解释解决以下问题的最佳方法, 相当奇怪的类型错误。假设我创建了一个像这样的元组列表:

scala> val ys = List((1,2), (3,4), (5,6))
ys: List[(Int, Int)] = List((1,2), (3,4), (5,6))

现在,如果我想将其映射到List(Int)

scala> ys.map((a: Int, b: Int) => a + b)
<console>:9: error: type mismatch;
found   : (Int, Int) => Int
required: ((Int, Int)) => ?
   ys.map((a: Int, b: Int) => a + b)
                           ^

任何线索?我知道我可以使用for comprehension

scala> for ((a, b) <- ys) yield a + b
res1: List[Int] = List(3, 7, 11)

但是在这种情况下破坏理解是错误的。谢谢!

2 个答案:

答案 0 :(得分:7)

尝试:

ys.map { case (a: Int, b: Int) => a + b }

或:

ys.map(p: (Int, Int) => p._1 + p._2)

正在发生的事情是ysList (Int,Int),所以map期望来自单个参数的函数,恰好是元组{{1} },到其他东西(技术上,(Int,Int)期望参数为map。函数Function1[(Int,Int),Int]实际上不是从单个参数(a: Int, b: Int) => a+b(Int, Int)的函数;相反,它是两个参数的函数,Int s,Int(a Int)。差异很微妙,但是重要因为Scala有所区别:

Function2[Int,Int,Int]

在答案的顶部解释我的建议:在第一个示例中,我们更改了赋予val f: Function1[(Int,Int),Int] = (p: (Int,Int)) => p._1 + p._2 ys.map(f) // fine val g: Function1[(Int,Int),Int] = { case (a: Int, b: Int) => a + b } ys.map(g) // fine, technically a PartialFunction[(Int,Int),Int] val h: Function2[Int,Int,Int] = (a: Int, b: Int) => a + b ys.map(h) // ERROR! 的函数的定义以使用map,这告诉Scala解压缩单{{ {1}}论证分为两部分。 (还要注意使用花括号而不是括号。)在第二个例子中,我们有一个单元组参数case的函数,我们手动提取元组的每个部分。

最后,请注意您也不需要类型注释。这些工作也一样:

(Int,Int)

答案 1 :(得分:0)

尝试:

val ys = List((1,2),(3,4),(5,6))
ys map(t =&gt; t._1 + t._2)