Decomposing tuples in function arguments
Asked Answered
S

3

72

In python I can do this:

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

d = (1, 2)
f(d)

Here the passed in tuple is being decomposed while its being passed to f.

Right now in scala I am doing this:

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

val d = (1, 2)
f(d)

Is there something I can do here so that the decomposition happens while the arguments are passed in? Just curious.

Spahi answered 23/7, 2012 at 15:29 Comment(2)
Interesting. I didn’t know this was even possible in Python.Heilbronn
Also: issues.scala-lang.org/browse/SI-813Heilbronn
C
100

You can create a function and match its input with pattern matching:

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

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

Or match the input of the method with the match keyword:

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

Another way is to use a function with two arguments and to "tuple" it:

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
Cly answered 23/7, 2012 at 15:34 Comment(0)
M
8

Starting in Scala 3, with the improved tupled function feature:

// val tuple = (1, 2)
// def f(a: Int, b: Int): Int = a + b
f.tupled(tuple)
// 3

Play with it in Scastie

Maggot answered 1/6, 2020 at 13:4 Comment(0)
P
-2
object RandomExperiments extends App{
  def takeTuple(t:(Int,Int))=print (s"$t ${t._1}\n")
  takeTuple(1,3)
  takeTuple((1,3))
  takeTuple(((1,3)))

}

prints:

(1,3) 1
(1,3) 1
(1,3) 1
Prefiguration answered 1/4, 2017 at 16:22 Comment(3)
This is basically the same as Brian Agnews answer. But maybe it was an April fools joke?Bonspiel
The first one works because one can use in scala the syntax without parentheses. It is not calling takeTuple with two parameters, it is calling takeTuple with one tuple parameter without wrapping the parameter with parentheses (which was actually done in #2).Wellbred
I have no idea of what you are trying to answer here.Fowl

© 2022 - 2024 — McMap. All rights reserved.