8

Given this pattern match:

List(1,2,3) match {
  case head :: tail => println(">>> head=" + head)
}

I'm assuming that '::' is the case class found in scala.collection.immutable, but how is '::' allowed to be written in that form (infix notation)? - is there a specific rule to allow for that?

Thanks

Dzhu
  • 4,311
  • 5
  • 36
  • 48
  • 2
    You may want to look at [Scala match decomposition on infix operator](http://stackoverflow.com/questions/1022218/scala-match-decomposition-on-infix-operator) and [How is this case class match pattern working?](http://stackoverflow.com/questions/1059145/how-is-this-case-class-match-pattern-working) – 4e6 Dec 29 '11 at 08:55

2 Answers2

26

You can even write:

val head :: tail = List(1, 2, 3)

Basically anything where a pattern is expected (an assignment, a match statement or a line in a for-comprehension) can take an extractor, which is defined as an entity with an unapply method.

One of the pieces of syntactic sugar that scala provides you with is that; if you have an extractor X(a, b), this can be written as a X b. Here's an example with case classes (which have a default extractor):

scala> case class X(a: Int, b: String)
defined class X

scala> val a X b = X(1, "two")
a: Int = 1
b: String = two

The ability to write such entities infix extends to types as well:

scala> type MappedTo[A, B] = Map[A, B]
defined type alias MappedTo

scala> def foo(m: Int MappedTo String) = m foreach println
foo: (m: MappedTo[Int,String])Unit

Note that in neither case, does scala restrict such infix operators to symbolic identifiers

oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
3

Scala actually has an immutable class :: which represents the non-empty list (the complement to Nil). There's an infix notation for classes (which is also how things like A <:< B work) which is allowing you to write head :: tail instead of ::(head, tail). Since :: is a case class it has a default unapply which makes case work as you illustrate.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150