14

can someone assist me understanding this code

case "Foo" Foo(data) -> _ => { /*.. implementation */}

I see the usage of Foo.unapply(data) but I don't understand what this part

-> _

how and when to use it

igx
  • 4,101
  • 11
  • 43
  • 88
  • There is a popular question that also cover your problem http://stackoverflow.com/questions/7888944/scala-punctuation-aka-symbols-and-operators – le-doude Aug 28 '13 at 15:24
  • 1
    btw you can easily understand this code if you use intellij http://gyazo.com/dcf31d20ccb925bed0e302fd45df7710.png or if you process it with scala x-ray http://scastie.org/2026 – OlegYch Aug 28 '13 at 17:32

1 Answers1

27

It looks like someone is being way too clever for their own good. Suppose I've got the following:

case class Foo[A](command: String, data: A)

object -> { def unapply[A, B](p: (A, B)) = Some(p) }

Now I can write this:

scala> Foo("foo", (42, 'whatever)) match {
     |   case "foo" Foo(data) -> _ => data
     | }
res0: Int = 42

Thanks to the magic of Scala's infix patterns, this is equivalent to the following:

Foo("foo", (42, 'whatever)) match {
  case Foo("foo", data -> _) => data
}

Except that the infix version is guaranteed to confuse and annoy your code's future readers.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • 1
    +1 because you understood the case right away. And for the scala magic – le-doude Aug 28 '13 at 15:30
  • 1
    Wow. I didn't know that the compiler could perform _that_ transform--moving the `-> _` inside the parens, essentially? Or is that not what's going on? – Rex Kerr Aug 28 '13 at 15:51
  • 2
    @RexKerr: The parentheses aren't actually doing any work here—you could just as well (i.e., horribly) write `case "foo" Foo data -> _`. – Travis Brown Aug 28 '13 at 15:53
  • 2
    Oh, oh, of course. It is _so_ tempting to interpret `Foo(...)` as the highest precedence instead of parens as a useless wrapper around `data`. – Rex Kerr Aug 28 '13 at 15:55
  • 1
    That is definitely a Scala puzzler! – kiritsuku Aug 28 '13 at 16:03
  • Can you please link in the reference on how it converts `"foo" Foo(data) -> _` to `Foo("foo", data -> _)`. I have seen this with `=:=` also where `=:=[A,B]` is same as `A =:= B`. I do not know by what to search in reference for this – Jatin Aug 28 '13 at 17:08
  • unconventional use of parentheses may be confusing, but otherwise it's definitely not a puzzler, e.g. something like case a :: b :: Nil => is something you encounter on the first day of scala – OlegYch Aug 28 '13 at 17:13
  • @OlegYch: A puzzler's no fun if it doesn't take more or less everyday ingredients and turn them into something ghastly. This definitely fits the bill. – Travis Brown Aug 28 '13 at 17:31
  • @Jatin: Look up 8.1.10 ("Infix Operation Patterns") in the Scala reference. – Travis Brown Aug 28 '13 at 17:39
  • @TravisBrown thanks , one question - why data yields the 42 and not the "whatever" ? – igx Aug 30 '13 at 11:57
  • @igx: `data -> _` is desugared to `->(data, _)`, and when we match `(42, 'whatever)` against that, we end up with `data` having the value `42`. – Travis Brown Aug 30 '13 at 12:01
  • @TravisBrown Thanks ! that certainty clarify this issue – igx Aug 30 '13 at 12:25