59

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.

5 Answers 5

80

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> 
Sign up to request clarification or add additional context in comments.

3 Comments

interesting to note, scala (2.11.0 here) will bring your untupled params up to a tuple if you do: fft.apply(1,2)
Good to know you can do this, but this seems not much shorter than just using function(tup._1,tup._2) in the first place
@AllenWang I think the important point is that tupled can be used for any arity. Good for maintainability.
18

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.

Comments

8

Scala 2.13

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

1 Comment

Thanks for your answer, but adding some explanation perhaps could help more people
1
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 

Comments

1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.