scala tuple拆包

sco*_*out 90 parameters scala tuples

我知道这个问题以不同的方式出现过很多次.但我现在还不清楚.有没有办法实现以下目标.

def foo(a:Int, b:Int) = {}

foo(a,b) //right way to invoke foo

foo(getParams) // is there a way to get this working without explicitly unpacking the tuple??

def getParams = {
   //Some calculations
   (a,b)  //where a & b are Int
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ith 103

这是一个两步程序.首先将foo转换为函数,然后在其上调用tupled以使其成为元组的函数.

(foo _).tupled(getParams)
Run Code Online (Sandbox Code Playgroud)

  • 是的,如果Scala统一它对元组和参数列表的处理,那将会更加清晰.从我所听到的,有很多非显而易见的边缘情况需要仔细处理才能实现.据我所知,元组和参数列表的统一目前不在Scala路线图上. (12认同)
  • 如果斯卡拉只是把争论视为元组开始,那会不会更清晰? (3认同)
  • 只是要添加,如果foo是伴随对象的工厂方法,可以使用(Foo.apply _).tupled(getParams) (2认同)

Bre*_*ams 54

@ dave-griffith已经死了.

你也可以打电话:

Function.tupled(foo _)
Run Code Online (Sandbox Code Playgroud)

如果你想进入"比我要求的更多信息"领域,还有一些内置于部分应用函数(和Function)的方法用于currying.一些输入/输出示例:

scala> def foo(x: Int, y: Double) = x * y
foo: (x: Int,y: Double)Double

scala> foo _
res0: (Int, Double) => Double = <function2>

scala> foo _ tupled
res1: ((Int, Double)) => Double = <function1>

scala> foo _ curried
res2: (Int) => (Double) => Double = <function1>

scala> Function.tupled(foo _)
res3: ((Int, Double)) => Double = <function1>

// Function.curried is deprecated
scala> Function.curried(foo _)
warning: there were deprecation warnings; re-run with -deprecation for details
res6: (Int) => (Double) => Double = <function1>
Run Code Online (Sandbox Code Playgroud)

其中使用多个参数列表调用curried版本:

scala> val c = foo _ curried
c: (Int) => (Double) => Double = <function1>

scala> c(5)
res13: (Double) => Double = <function1>

scala> c(5)(10)
res14: Double = 50.0
Run Code Online (Sandbox Code Playgroud)

最后,如果需要,您还可以进行uncurry/untuple. Function为此建立了:

scala> val f = foo _ tupled
f: ((Int, Double)) => Double = <function1>

scala> val c = foo _ curried
c: (Int) => (Double) => Double = <function1>

scala> Function.uncurried(c)
res9: (Int, Double) => Double = <function2>

scala> Function.untupled(f)
res12: (Int, Double) => Double = <function2>
Run Code Online (Sandbox Code Playgroud)


mis*_*tor 20

Function.tupled(foo _)(getParams)或戴夫建议的那个.

编辑:

回复你的评论:

如果foo恰好是某类的构造函数怎么办?

在这种情况下,这个技巧将不起作用.

您可以在类的伴随对象中编写工厂方法,然后apply使用上述技术之一获取其方法的tupled版本.

scala> class Person(firstName: String, lastName: String) {
     |   override def toString = firstName + " " + lastName
     | }
defined class Person

scala> object Person {
     |   def apply(firstName: String, lastName: String) = new Person(firstName, lastName)
     | }
defined module Person

scala> (Person.apply _).tupled(("Rahul", "G"))
res17: Person = Rahul G
Run Code Online (Sandbox Code Playgroud)

使用case classes,你可以获得一个带有apply免费方法的伴随对象,因此这种技术使用case classes 更方便.

scala> case class Person(firstName: String, lastName: String)
defined class Person

scala> Person.tupled(("Rahul", "G"))
res18: Person = Person(Rahul,G)
Run Code Online (Sandbox Code Playgroud)

我知道这是很多代码重复但是唉...我们还没有宏(还)!;)

  • 在这里的最后一个例子中,你可以稍微削减一下......案例类的伴随对象总是扩展适当的FunctionN特性.所以最后一行可能是``Person.tupled(("Rahul","G"))``在手写的伴侣对象中也很方便. (3认同)