распаковка scala tuple

Я знаю, что этот вопрос возник много раз по-разному. Но мне все еще не ясно. Есть ли способ достичь следующего.

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 } 

Это двухэтапная процедура. Сначала включите foo в функцию, а затем вызовите его, чтобы сделать его функцией кортежа.

 (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 =  scala> foo _ tupled res1: ((Int, Double)) => Double =  scala> foo _ curried res2: (Int) => (Double) => Double =  scala> Function.tupled(foo _) res3: ((Int, Double)) => Double =  // Function.curried is deprecated scala> Function.curried(foo _) warning: there were deprecation warnings; re-run with -deprecation for details res6: (Int) => (Double) => Double =  

В том случае, когда версия curried вызывается с несколькими списками аргументов:

 scala> val c = foo _ curried c: (Int) => (Double) => Double =  scala> c(5) res13: (Double) => Double =  scala> c(5)(10) res14: Double = 50.0 

Наконец, вы также можете раскручивать / отключать, если необходимо. Function имеет встроенные Function для этого:

 scala> val f = foo _ tupled f: ((Int, Double)) => Double =  scala> val c = foo _ curried c: (Int) => (Double) => Double =  scala> Function.uncurried(c) res9: (Int, Double) => Double =  scala> Function.untupled(f) res12: (Int, Double) => Double =  

Function.tupled(foo _)(getParams) или тот, который предложил Дейв.

РЕДАКТИРОВАТЬ:

Чтобы ответить на ваш комментарий:

Что, если foo оказывается конструктором некоторого classа?

В этом случае этот трюк не будет работать.

Вы можете написать фабричный метод в сопутствующем объекте вашего classа, а затем получить положенную версию метода его 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) 

Я знаю, что много дублирования кода, но увы … у нас нет макросов (пока)! 😉

Я ценю некоторые из других ответов, которые были ближе к тому, что вы просили, но мне было легче, если бы текущий проект добавил еще одну функцию, которая преобразует параметры кортежа в параметры разделения:

 def originalFunc(a: A, b: B): C = ... def wrapperFunc(ab: (A, B)): C = (originalFunc _).tupled(ab) 

Теперь вы можете реализовать foo и сделать так, чтобы он соответствовал параметру classа 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) 
Давайте будем гением компьютера.