Pattern matching lets you automatically execute code based on some piece of data. Scala uses pattern matching often, such as when you parse XML or pass messages between threads. Basic syntax of pattern matching is as follow.
target match { case _ => result }
Following are the important aspects of pattern matching:
Pattern matching works a bit like a switch
statement.
def dochore(chore:String):String = chore match{ case "A" => "A" case "B" => "B" case _ => "C" }
A pattern matches a target if it is structurally equivalent to the pattern in question. If multiple pattern matches the target, Scala chooses the first matching case.
List(1,2,3) match { case _ => 42} // => 42 List(1,2,3) match { case h::t => h} // => 1 List(1,2,3) match { case h::t => t} // => List(2,3)
If none of the patterns matches with the target, MatchError
occurs. A MatchError
indicates that the none of the cases in a match expression matched the target.
List(1,2,3) match {case Nil => 42} // => `MatchError` at runtime.
Next, we outline few concrete examples.
Examples
Example1: Computing Factorial. To compute a factorial in Scala, we specify a condition in a guard for each match statement.
def factorial(n: Int): Int = n match { case 0 => 1 case x if x>0 => factorial(n-1) *n }
Example 2: Computing summation of a given List as an argument. To do this, we need to define a function with signature: def sum(l:List[int])
and implement it as follows.
def sum (list:List[Int]) = { def sumAux (xs:List[Int], res:Int):Int = xs match { case Nil => res case x::xt => sumAux(xt, res+x) <span class="bullet rounded">1</span> } sumAux (list, 0) }
Example 3: Computing Product is taken from Functional Programming in Scala book.
sealed trait List[+A] case object Nil extends List[Nothing] case class(head: A, tail:List[A]) extends List[A] def product(ds: List[Double]): Double = ds match{ case Nil => 1.0 case Cons(0,0,_) => 0.0 case Cons(x, xs) => x * product(xs) }