John Clements
John Clements

Reputation: 17233

How to apply a function to a tuple?

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.

Upvotes: 59

Views: 31311

Answers (5)

user
user

Reputation: 7604

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.

Upvotes: 1

jwvh
jwvh

Reputation: 51271

Scala 2.13

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

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

Upvotes: 8

Randall Schulz
Randall Schulz

Reputation: 26486

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>

Upvotes: 80

Val K
Val K

Reputation: 105

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

Upvotes: 1

Jacek Laskowski
Jacek Laskowski

Reputation: 74779

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.

Upvotes: 18

Related Questions