web-dev-qa-db-fra.com

Scala: Décomposer des n-uplets en arguments de fonction

En python, je peux faire ceci:

def f((a, b)):
    return a + b

d = (1, 2)
f(d)

Ici, le tuple transmis est décomposé alors qu'il est passé à f.

En ce moment en scala je fais ceci:

def f(ab:(Int, Int)) : Int = {
    val (a, b) = ab
    a + b
}
val d = (1, 2)
f(d)

Est-ce que je peux faire quelque chose ici pour que la décomposition se produise pendant que les arguments sont transmis? Juste curieux.

Merci. 

54
verma

Vous pouvez créer une fonction et faire correspondre son entrée avec une correspondance de modèle:

scala> val f: ((Int, Int)) => Int = { case (a,b) => a+b }
f: ((Int, Int)) => Int

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

Ou faites correspondre l'entrée de la méthode avec le mot clé match:

scala> def f(ab: (Int, Int)): Int = ab match { case (a,b) => a+b }
f: (ab: (Int, Int))Int

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

Une autre façon est d'utiliser une fonction avec deux arguments et de la "tupler":

scala> val f: (Int, Int) => Int = _+_
f: (Int, Int) => Int = <function2>

scala> val g = f.tupled // or Function.tupled(f)
g: ((Int, Int)) => Int = <function1>

scala> g(1, 2)
res10: Int = 3

// or with a method
scala> def f(a: Int, b: Int): Int = a+b
f: (a: Int, b: Int)Int

scala> val g = (f _).tupled // or Function.tupled(f _)
g: ((Int, Int)) => Int = <function1>

scala> g(1, 2)
res11: Int = 3

// or inlined
scala> val f: ((Int,Int)) => Int = Function.tupled(_+_)
f: ((Int, Int)) => Int = <function1>

scala> f(1, 2)
res12: Int = 3
81
kiritsuku
object RandomExperiments extends App{
  def takeTuple(t:(Int,Int))=print (s"$t ${t._1}\n")
  takeTuple(1,3)
  takeTuple((1,3))
  takeTuple(((1,3)))

}

impressions:

(1,3) 1
(1,3) 1
(1,3) 1
0
jhegedus