私はこの質問がさまざまな方法で何度も出てきたことを知っています。しかし、私にはまだ明確ではありません。以下を達成する方法はありますか。
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
}
これは2段階の手順です。最初にfooを関数に変換し、次にそれをタプルして呼び出してTupleの関数にします。
(foo _).tupled(getParams)
@ dave-griffithは死んでいます。
以下を呼び出すこともできます。
Function.tupled(foo _)
「私が要求したよりも多くの情報」領域に行きたい場合、カリー化のために部分的に適用された関数(およびFunction
)に組み込まれたメソッドもあります。いくつかの入力/出力の例:
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>
カリー化されたバージョンは、複数の引数リストで呼び出されます:
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
最後に、必要に応じて、カレー/アンタプルもできます。 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>
Function.tupled(foo _)(getParams)
またはDaveによって提案されたもの。
編集:
コメントに返信するには:
fooが何らかのクラスのコンストラクターである場合はどうなりますか?
その場合、このトリックは機能しません。
クラスのコンパニオンオブジェクトにファクトリメソッドを記述し、前述の手法のいずれかを使用して、そのapply
メソッドのタプルバージョンを取得できます。
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
case class
es apply
メソッドを持つコンパニオンオブジェクトを無料で取得できます。したがって、この手法はcase class
es。
scala> case class Person(firstName: String, lastName: String)
defined class Person
scala> Person.tupled(("Rahul", "G"))
res18: Person = Person(Rahul,G)
私はそれが多くのコードの重複であることを知っていますが、悲しいかな...私たちにはマクロがありません(まだ)! ;)
あなたが求めたものに近い他の回答のいくつかを感謝しますが、現在のプロジェクトがTupleパラメータを分割パラメータに変換する別の関数を追加する方が簡単であることがわかりました:
def originalFunc(a: A, b: B): C = ...
def wrapperFunc(ab: (A, B)): C = (originalFunc _).tupled(ab)
これで、fooを実装して、Tuple2クラスのパラメーターを取得することができます。
def foo(t: Tuple2[Int, Int]) = {
println("Hello " + t._1 + t._2)
"Makes no sense but ok!"
}
def getParams = {
//Some calculations
val a = 1;
val b = 2;
(a, b) //where a & b are Int
}
// So you can do this!
foo(getParams)
// With that said, you can also do this!
foo(1, 3)