9

I (inadvertently) came across a bit of pattern matching syntax I did not expect to compile and now cannot figure out.

It appears related to unapplySeq.

Note the case x List(_,_) part in this simple example:

val xs = List(1, 2, 3)                          //> xs  : List[Int] = List(1, 2, 3)

xs match {
    case x List (_, _) => "yes"
    case _             => "no"
}                                               //> res0: String = yes

I am used to : or @ in pattern match syntax, but am confused about this. How does this syntax work and what (if any) is its relationship to unapplySeq?

Sample code executed in Scala 2.11.6

Brian Kent
  • 3,754
  • 1
  • 26
  • 31

1 Answers1

3

The equivalent non-infix version is:

xs match {
  case List(x, _, _) => "yes"
  case _             => "no"
}

Scala specification says:

An infix operation pattern p;op;q is a shorthand for the constructor or extractor pattern op(p,q). The precedence and associativity of operators in patterns is the same as in expressions.

An infix operation pattern p;op;(q1,…,qn) is a shorthand for the constructor or extractor pattern op(p,q1,…,qn).

bjfletcher
  • 11,168
  • 4
  • 52
  • 67
  • Where do you explain how `case List(x, _, _) => "yes"` would be equivalent to `case x List(_, _) => "yes"` ? – Régis Jean-Gilles Jun 22 '15 at 16:30
  • Infix operator notation is where the method sits in between the object and and parameter (or parameters). – bjfletcher Jun 22 '15 at 16:37
  • I thought infix notation only applied to functions with 2 arguments?? Looking at the source, `List.unapplySeq` is defined `def unapplySeq[A](x: CC[A]): Some[CC[A]] = Some(x)` – Brian Kent Jun 22 '15 at 16:44
  • 1
    @bjfletcher: I know what infix notation is, and this does not look like it. If it was, I assume that similarly constructing a list as in `List(1,2,3)` could also be done by doing `1 List(2, 3)` (which does not make much sense, and indeed does not compile) – Régis Jean-Gilles Jun 22 '15 at 16:57
  • 2
    I cannot, for instance, write `val xs = 1 List (2, 3)` to get a `List(1, 2, 3)` – Brian Kent Jun 22 '15 at 16:58
  • Ah ah, beat you to it ;-) Yes exactly. In addition, if infix notation is indeed supported in pattern matching, a reference would be welcome, as it is far from obvious. None of the quotes above make any mention of this. – Régis Jean-Gilles Jun 22 '15 at 17:00
  • 1
    http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#infix-operation-patterns – bjfletcher Jun 22 '15 at 17:39
  • 2
    Wow, that is extremely unintuitive!!! It seems it has nothing to do with `unapplySeq` then. Given a definition `case class Foo(a:Int, b:Int, c:Int)`, then an instance `Foo(1, 2, 3)` would match the pattern `case 1 Foo(2, 3)`. – Brian Kent Jun 22 '15 at 17:57
  • @bjfletcher: now that's some useful reference. I canl only agree with Brian Kent, very unintuitive indeed. – Régis Jean-Gilles Jun 22 '15 at 20:39