1

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

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 理解

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

但是在这种情况下打破理​​解感觉是错误的。谢谢!

4

2 回答 2

7

尝试:

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

或者:

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

发生的事情是ysa Listof (Int,Int),所以map期望一个函数来自一个单独的参数,它恰好是一个 tuple (Int,Int),到其他东西(从技术上讲,map期望一个参数Function1[(Int,Int),Int]。该函数(a: Int, b: Int) => a+b实际上不是一个来自单个参数的函数(Int, Int)Int相反,它是两个参数的函数,都是Ints,到Int(a Function2[Int,Int,Int]). 区别是微妙的,但很重要,因为 Scala 做出了区分:

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为 use case,它告诉 Scala 将单个(Int,Int)参数解压缩为两部分。(还要注意使用花括号而不是括号。)在第二个示例中,我们有一个单个元组参数的函数,p我们手动提取元组的每个部分。

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

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

ys.map(p => p._1 + p._2)
于 2012-04-10T02:46:24.337 回答
0

尝试:

  val ys = List((1,2),(3,4),(5,6))
  ys 映射 (t => t._1 + t._2)

于 2012-04-10T12:30:34.010 回答