Skip to content
AgileLogics
5 min read

Match Expressions

Prerequisites: Blocks and expressions

match compares a value against patterns — like a much more powerful switch.

@main def days(): Unit =
  val day = "Saturday"
  val kind = day match
    case "Saturday" | "Sunday" => "weekend"
    case "Friday"              => "almost weekend"
    case _                     => "weekday"
  println(kind)
weekend
  • Each case is a pattern, followed by => and the result.
  • | combines alternatives.
  • _ is the wildcard: it matches anything, like default.
  • Cases are checked in order, and only the first match runs — there's no fall-through.
  • Like if, match returns a value.

Guards and bindings

@main def grades(): Unit =
  for score <- List(95, 84, 71, 40) do
    val grade = score match
      case s if s >= 90 => "A"
      case s if s >= 80 => "B"
      case s if s >= 70 => "C"
      case _            => "F"
    println(s"$score -> $grade")
95 -> A
84 -> B
71 -> C
40 -> F

case s if ... binds the value to the name s and adds a guard — the case matches only if the condition is true.

Matching on types and tuples

def describe(x: Any): String = x match
  case 0              => "zero"
  case n: Int         => s"the number $n"
  case s: String      => s"a string of length ${s.length}"
  case (a, b)         => s"a pair of $a and $b"
  case _              => "something else"

@main def matching(): Unit =
  println(describe(0))
  println(describe(42))
  println(describe("hello"))
  println(describe((1, "one")))
  println(describe(3.14))
zero
the number 42
a string of length 5
a pair of 1 and one
something else

This is just the beginning: Level 2 shows how match takes apart case classes and data structures, which is where it really shines.

Common mistakes

  • Forgetting a catch-all case. If no case matches, the program throws a MatchError at runtime.