Pattern Matching

Matching on a sealed type or enum warns if cases are missing:

15.1 Kinds of patterns

def describe(x: Any): String = x match
  case 0 => "zero"                                  // literal
  case i: Int if i < 0 => "negative int"           // type pattern + guard
  case i: Int => s"int $i"
  case "hello" | "hi" => "greeting"                 // alternatives
  case s: String => s"string of length ${s.length}"
  case (a, b) => s"pair $a, $b"                     // tuple
  case List() => "empty list"
  case List(single) => s"one element: $single"
  case head :: tail => s"list starting with $head"  // cons pattern
  case Some(v) => s"some $v"
  case None => "none"
  case p @ Person(name, _) => s"person $name ($p)"  // binder @
  case _: Throwable => "an exception"
  case _ => "something else"                        // wildcard

15.2 Sequence patterns

xs match
  case Seq(first, second, rest*) => s"$first, $second and ${rest.size} more"
  case Seq(only) => s"just $only"
  case Seq() => "empty"

15.3 Exhaustiveness checking

Matching on a sealed type or enum warns if cases are missing:

def f(c: Color) = c match
  case Color.Red => 1
  case Color.Green => 2
// warning: match may not be exhaustive. It would fail on: Blue

15.4 Custom extractors

object Email:
  def unapply(s: String): Option[(String, String)] =
    s.split("@") match
      case Array(user, domain) => Some((user, domain))
      case _ => None

"ann@example.com" match
  case Email(user, domain) => s"$user at $domain"
  case _ => "not an email"

object Even:
  def unapply(n: Int): Boolean = n % 2 == 0    // boolean extractor

object Words:
  def unapplySeq(s: String): Option[Seq[String]] = Some(s.split("\\s+").toSeq)   // variadic

"a b c" match { case Words(first, _*) => first }

15.5 Patterns in other places

val (a, b) = (1, 2)
val head :: _ = List(1, 2, 3): @unchecked
for (k, v) <- Map("a" -> 1) do println(s"$k=$v")
list.map { case (k, v) => k + v }
list.collect { case Some(x) if x > 0 => x }
val Some(cfg) = loadConfig(): @unchecked

15.6 Regex patterns

val Date = raw"(\d{4})-(\d{2})-(\d{2})".r
"2026-10-25" match
  case Date(y, m, d) => s"year $y"
  case _ => "no match"

15.7 Matching on types with generics (erasure)

Use ClassTag/TypeTest (§29) for safe runtime type checks of generics.

x match
  case xs: List[Int] => ...   // warning: unchecked since it is eliminated by erasure