54 votes

Comment appliquer une fonction à un tuple ?

Cela devrait être facile. Comment appliquer une fonction à un tuple en Scala ? Viz :

scala> def f (i : Int, j : Int) = i + j
f: (Int,Int)Int

scala> val p = (3,4)
p: (Int, Int) = (3,4)

scala> f p
:6: error: missing arguments for method f in object $iw;
follow this method with \`\_' if you want to treat it as a partially applied function
       f p
       ^

scala> f \_ p
:6: error: value p is not a member of (Int, Int) => Int
       f \_ p
           ^

scala> (f \_) p
:6: error: value p is not a member of (Int, Int) => Int
       (f \_) p
             ^

scala> f(p)
:7: error: wrong number of arguments for method f: (Int,Int)Int
       f(p)
       ^

scala> grr!

Merci d'avance.

72voto

Randall Schulz Points 18820

Dans Scala 2.8 et plus récent :

scala> def f (i : Int, j : Int) = i + j
f: (i: Int,j: Int)Int

// Note the underscore after the f
scala> val ff = f _
ff: (Int, Int) => Int = <function2>

scala> val fft = ff.tupled
fft: ((Int, Int)) => Int = <function1>

Dans Scala 2.7 :

scala> def f (i : Int, j : Int) = i + j
f: (Int,Int)Int

// Note the underscore after the f
scala> val ff = f _
ff: (Int, Int) => Int = <function>

scala> val fft = Function.tupled(ff)
fft: ((Int, Int)) => Int = <function>

1 votes

Il est intéressant de noter que scala (2.11.0 ici) transformera vos paramètres non nuclés en un tuple si vous le faites : fft.apply(1,2)

0 votes

Il est bon de savoir que vous pouvez le faire, mais cela ne semble pas beaucoup plus court que de simplement utiliser function(tup._1,tup._2) en premier lieu

3 votes

@AllenWang Je pense que le point important est que tupled peut être utilisé pour n'importe quelle arité. Bon pour la maintenabilité.

17voto

Jacek Laskowski Points 6668

Pour faire suite à l'autre réponse, on pourrait écrire (testé avec 2.11.4) :

scala> def f (i: Int, j: Int) = i + j
f: (i: Int, j: Int)Int

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

scala> val p = (3,4)
p: (Int, Int) = (3,4)

scala> ff.tupled(p)
res0: Int = 7

Voir def tupled : ((T1, T2)) ⇒ R=%3ER) :

Crée une version tuplée de cette fonction : au lieu de 2 arguments, elle accepte un seul scala.Tuple2 argument.

4voto

jwvh Points 23682

Scala 2.13

def f (i : Int, j : Int) = i + j

import scala.util.chaining._
(3,4).pipe((f _).tupled)   //res0: Int = 7

0voto

Val K Points 95
scala> def f (i: Int, j: Int) = i + j
f: (i: Int, j: Int)Int
scala> val p = (3,4)
p: (Int, Int) = (3,4)
scala> val ft = (f _).tupled
ft: ((Int, Int)) => Int = <function1>
scala> ft apply(p)
res0: Int = 7

0voto

user Points 6733

En Scala 3, vous pouvez utiliser TupledFunction :

Pour une seule utilisation, vous pouvez faire

summon[TupledFunction[(Int, Int) => Int, ((Int, Int)) => Int]].tupled(f)((2, 3))

Pour faciliter son utilisation, vous pouvez utiliser une extension (copiée de la propre documentation de Dotty)

extension [F, T <: Tuple, R](f: F)(using tf: TupledFunction[F, T => R])
  def tupled(t: T): R = tf.tupled(f)(t)

Et ensuite vous pouvez faire f.tupled((2, 3)) pour obtenir 5 .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X