Is destructuring input parameters available in Scala?
Asked Answered
G

4

16

Is there a way to destructure input parameters of a function in Scala (akin to Clojure)?

So, instead of

scala> def f(p: (Int, Int)) = p._1
f: (p: (Int, Int))Int

I'd like to have this (it doesn't work):

scala> def f((p1, p2): (Int, Int)) = p1
Gab answered 1/5, 2013 at 21:0 Comment(1)
Request for the same in Scala's issue tracker: issues.scala-lang.org/browse/SI-7909Devi
E
18

I guess in scala you would use pattern matching to achieve the same, e.g. like this:

val f: (Int, Int) => Int = { case (p1, p2) => p1 }

Or, equivalently:

def f(p: (Int, Int)) = p match { case(p1, p2) => p1 }

If the types can be inferred, the (Int, Int) => Int can be dropped:

List((1, 2), (3, 4)) map { case (p1, p2) => p1 }
Erythrite answered 1/5, 2013 at 21:5 Comment(3)
I'd rather avoid using pattern matching as a too verbose solution. I can accept it, though, if there's no other, idiomatic approach. Is there one?Gab
@JacekLaskowski - This is the best you're going to get. Tuples and method parameters aren't fully unified, and this is one of the places where you notice. You can, however, def f(p1: Int, p2: Int) = p1+p2 and then (f _).tupled to create a function that takes a tuple even though the def took separate parameters.Antimonyl
So the short answer is no.Budwig
P
0
def f(p: ((Int, Int), (Int, Int))) = p._1     > f: (p: ((Int, Int), (Int, Int)))(Int, Int)
f((1,2), (3,4))                               > res1: (Int, Int) = (1,2)
Phonotypy answered 2/5, 2013 at 4:57 Comment(0)
A
0

It really depends on what problem you are trying to solve, but one idea is to use a tupled-function. In other words, define a function that takes two parameters, and .tupled it:

Welcome to Scala 3.2.1 (11.0.21, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                
scala> def f_(p1: Int, p2: Int): Int = p1
def f_(p1: Int, p2: Int): Int
                                                                                
scala> val f = f_.tupled
val f: ((Int, Int)) => Int = scala.Function2$$Lambda$1337/0x0000000800737840@e6e5da4
                                                                                
scala> val pair = (1, 2)
val pair: (Int, Int) = (1,2)
                                                                                
scala> f(pair)
val res0: Int = 1
Ameeameer answered 8/5 at 13:23 Comment(0)
S
0

Yes

def f(pair:(Int, Int)): Int =
    val (p1, p2) = pair
    p1

but why not just do?

def f(pair:(Int, Int)): Int = pair(0)
Semifinal answered 9/5 at 18:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.