在map,flatmap,...部分函数中使用元组

时间:2014-04-08 17:44:44

标签: scala tuples partialfunction

如果我这样做:

val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { t => t._1 + t._2 }

没关系。

如果我这样做:

val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { case (b, n) => b + n }

也没问题。

但如果我这样做:

val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { (b, n) => b + n }

它不起作用。
我为什么要使用" case"使用命名元组的关键字?

3 个答案:

答案 0 :(得分:6)

2.11的错误消息更具说明性:

scala> l map { (b, n) => b + n }
<console>:9: error: missing parameter type
Note: The expected type requires a one-argument function accepting a 2-Tuple.
      Consider a pattern matching anonymous function, `{ case (b, n) =>  ... }`
              l map { (b, n) => b + n }
                       ^
<console>:9: error: missing parameter type
              l map { (b, n) => b + n }
                          ^

对于申请,您将获得“自动翻译”:

scala> def f(p: (Int, Int)) = p._1 + p._2
f: (p: (Int, Int))Int

scala> f(1,2)
res0: Int = 3

你提供了两个args而不是一个。

但你没有得到自动解决。

人们有always wanted it to work that way

答案 1 :(得分:1)

使用types内部函数可以理解这种情况。

首先,map函数的参数函数的类型语法如下:

Tuple2[Int,Int] => B //Function1[Tuple2[Int, Int], B]

第一个参数功能扩展到此。

(t:(Int,Int)) => t._1 + t._2 // type : Tuple2[Int,Int] => Int

这没关系。然后是第二个功能。

(t:(Int, Int)) => t match {
  case (a:Int, b:Int) => a + b
}

这也没关系。在故障情形中,

(a:Int, b:Int) => a + b 

让我们检查一下功能的类型

(Int, Int) => Int // Function2[Int, Int, Int]

所以参数函数类型错误。

作为一种解决方案,您可以使用Function对象中的辅助函数将多个arity函数转换为元组模式并向后转换。你可以这样做。

val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map(Function.tupled((b, n) => b + n ))

请参阅Function API了解更多信息。

答案 2 :(得分:0)

传递给应用于序列的map函数的函数参数的类型由序列中元素的类型推断。特别是,

方案1:l map { t => t._1 + t._2 }l map { t: ((String, String)): (String) => t._1 + t._2 }相同但更短,这可能是因为类型推断。 Scala编译器自动推断参数的类型为(String, String) => String

方案2:你也可以用更长的形式写作

l map { t => t match {
    case(b, n) => b + n
  }
}

方案3:将错误类型的函数传递给map,类似于

def f1 (a: String, b: String) = a + b

def f2 (t: (String, String)) = t match { case (a, b) => a + b }

l map f1 // won't work

l map f2