Object fields desctructuring

It’s obvious that Scala’s pattern matching allow destructuring or better say deconstructing objects, coming from a JS context, seems strange that destructuring cannot be used outside pattern matching, for example in lambdas or var declarations. Is something like that even possible/desirable in Scala? with the idea in mind that pattern matching has a different and more general mechanism than just only extracting fields.

Notice that Kotlin supports destructuring for both lambdas and declarations, on the other hand that it does not support destructuring for when expressions, the closest analogue of pattern matching.

Well, you actually can use pattern matching in more places in scala, for instance:

case class Foo(a: Int, b: String)

val x = List(Foo(2, "a"), Foo(3, "b")).map {
  case Foo(a, _) => a
}

or even

val (a, b) = Foo(2, “b”)
3 Likes

Is what @gabro showed what you were wishing for ?

If yes, that’s nice to hear!
I think it would be very interesting to know why you thought this was not possible, as this might indicate tutorials/articles/… do not give the correct impression

If not, then maybe you can clarify so we can discuss the benefits/drawbacks of a different approach

1 Like

I’d like some proposal that allowed the following

import Foo.*

enum Foo:
  case Bar(s: String)
  case Baz(i: Int, b: Boolean)

def foo(Bar(s)) = s.length
def foo(Baz(i, b)) = if b then i * 3 else -i
1 Like

This is part of what i’m looking, however throws a warning, seems it wants to create a tuple form constructor parameters
image

It should be val Foo(a, b) = Foo(2, “b”). Or val (a, b) = (2, “b”).

3 Likes

It should be

val Foo(a, b) = Foo(2, "b")
3 Likes

If one insists on using tuples, there’s also:

 val (a, b) = Tuple.fromProductTyped(Foo(2, "b"))

Woops, yes, as other said you need the case class in the left hand side.

thanks it works for extracting into val/var, wonder if there is a way to make it work on lambda definition

image

Yes, like @gabro demonstrated in his post:

However if you want to store the lambda in a variable, you have to give it an explicit type for this to work.

val fun: Foo => Int = { case Foo(a, _) => a }
2 Likes