2012-04-10 115 views
1

有人可以解释最好的方式来解决以下, 相当好奇的类型错误。假设我创建元组的列表,像这样:斯卡拉地图/类型实例

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

现在,如果我想这映射到表(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) 
         ^

任何线索?我知道我可以用它来理解

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

但是在这种设置中破解理解感觉不对。谢谢!

回答

7

尝试:

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

或:

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

发生了什么事是ys(Int,Int)一个List,所以map预计从一个单一的参数,这恰好是一个元组(Int,Int)功能,到别的东西(技术上,map需要一个参数Function1[(Int,Int),Int]。函数(a: Int, b: Int) => a+b我实际上并不是从单个参数(Int, Int)Int;相反,它是两个参数(Int s)与Int(a 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函数的定义中使用case ,它告诉Scala将其中的两个部分解析为单个的参数。 (还要注意使用花括号代替圆括号。)在第二个例子中,我们有一个单元组参数p的函数,我们手动提取元组的每个部分。

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

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

ys.map(p => p._1 + p._2) 
+0

获得额外奖励积分可以降低这些Int类型归属! – 2012-04-10 02:55:29

+0

@亚当,你打败了我:-) – dhg 2012-04-10 02:56:11

+0

值得注意的是,使用“case”语句的解决方案是提供一个局部函数作为映射的参数,这就是为什么它能够立即取消应用该对。部分函数可以提供而不是常规函数的原因是部分函数扩展了函数。 – jwinder 2012-04-10 03:08:29

0

尝试:

    VAL YS =名单((1,2),(3,4),(5,6))
    YS地图(t => t._1 + t._2)