How to apply a function to a tuple?

Scala

Scala Problem Overview


This should be an easy one. How do I apply a function to a tuple in 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!

Many thanks in advance.

Scala Solutions


Solution 1 - Scala

In Scala 2.8 and newer:
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>
In 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>

Solution 2 - Scala

Following up on the other answer, one could write (tested with 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

See def tupled: ((T1, T2)) ⇒ R:

> Creates a tupled version of this function: instead of 2 arguments, it > accepts a single scala.Tuple2 argument.

Solution 3 - Scala

Scala 2.13

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

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

Solution 4 - Scala

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

Solution 5 - Scala

In Scala 3, you can use TupledFunction:

For a single use, you can do

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

To make it easier to use, you can use an extension (copied from Dotty's own documentation)

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

And then you can do f.tupled((2, 3)) to get 5.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn ClementsView Question on Stackoverflow
Solution 1 - ScalaRandall SchulzView Answer on Stackoverflow
Solution 2 - ScalaJacek LaskowskiView Answer on Stackoverflow
Solution 3 - ScalajwvhView Answer on Stackoverflow
Solution 4 - ScalaVal KView Answer on Stackoverflow
Solution 5 - ScalauserView Answer on Stackoverflow