Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala match case using :: for lists

Tags:

scala

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

like image 818
Dzhu Avatar asked Dec 29 '11 08:12

Dzhu


2 Answers

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

like image 104
oxbow_lakes Avatar answered Nov 18 '22 09:11

oxbow_lakes


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.

like image 32
Ben Jackson Avatar answered Nov 18 '22 08:11

Ben Jackson