简体   繁体   English

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

[英]Using Tuples in map, flatmap,… partial functions

If I do: 如果我做:

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

It's ok. 没关系。

If I do: 如果我做:

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

It's ok too. 也没关系。

But if I do: 但如果我这样做:

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

It will not work. 不起作用。
Why should I use "case" keyword to use named tuples? 为什么我应该使用“case”关键字来使用命名元组?

The error message with 2.11 is more explanatory: 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 }
                          ^

For an apply, you get "auto-tupling": 对于申请,您将获得“自动修改”:

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

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

where you supplied two args instead of one. 你提供了两个args而不是一个args。

But you don't get auto-untupling. 但是你没有得到自动解决。

People have always wanted it to work that way . 人们一直希望它以这种方式工作

This situation can be understand with the types of inner function. 这种情况可以通过内部函数的types来理解。

First, the type syntax of parameter function for the map function is as follows. 首先, map函数的参数函数的类型语法如下。

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

The first parameter function is expand to this. 第一个参数函数扩展到此。

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

This is ok. 还行吧。 Then the second function. 然后是第二个功能。

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

This is also ok. 这也没关系。 In the failure scenario, 在故障情形中,

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

Lets check the types of the function 让我们检查一下这个功能的类型

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

So the parameter function type is wrong. 所以参数函数类型错误。

As a solution, you can convert multiple arity functions to tuple mode and backward with the helper functions in Function object. 作为解决方案,您可以使用Function对象中的辅助函数将多个arity函数转换为元组模式并向后转换。 You can do following. 你可以做以下。

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

Please refer Function API for further information. 有关详细信息,请参阅Function API

The type of a function argument passed to map function applied to a sequence is inferred by the type of elements in the sequence. 传递给应用于序列的map函数的函数参数的类型由序列中元素的类型推断。 In particular, 特别是,

scenario 1: l map { t => t._1 + t._2 } is same as l map { t: ((String, String)): (String) => t._1 + t._2 } but shorter, which is possible because of type inference. 场景1: l map { t => t._1 + t._2 }l map { t: ((String, String)): (String) => t._1 + t._2 }但更短,由于类型推断是可能的。 Scala compiler automatically inferred the type of the argument to be (String, String) => String Scala编译器自动推断出参数的类型为(String, String) => String

scenario 2: you can also write in longer form 场景2:你也可以用更长的形式写作

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

scenario 3: a function of wrong type is passed to map, which is similar to 场景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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM