🎓 A1Learner
🔍
0 of 48 lessons completed

Scala Nested Patterns

A nested pattern is a pattern placed inside another pattern. It tests an outer shape and an inner shape in a single case.

A case class pattern sits inside a list pattern

The outer pattern takes the first list item. The inner pattern splits that point into x and y.

case class Point(x: Int, y: Int)
@main def main(): Unit =
  val result = List(Point(1, 2), Point(3, 4)) match
    case Point(x, y) :: _ => x + y
    case _ => 0
  println(result)

A case class pattern sits inside another case class

The outer pattern binds the name. The inner pattern binds the city from the address.

case class Address(city: String)
case class Person(name: String, address: Address)
@main def main(): Unit =
  val result = Person("Ana", Address("Paris")) match
    case Person(n, Address(c)) => n + " in " + c
    case _ => "no"
  println(result)

An Option pattern sits inside another Option

The outer Some holds another Some. The inner pattern binds the number inside both layers.

@main def main(): Unit =
  val v: Option[Option[Int]] = Some(Some(5))
  val result = v match
    case Some(Some(n)) => n
    case _ => 0
  println(result)

Example

case class Point(x: Int, y: Int)
case class Line(start: Point, end: Point)
def span(line: Line): String = line match
  case Line(Point(x1, y1), Point(x2, y2)) => (x2 - x1) + ":" + (y2 - y1)
@main def main(): Unit =
  println(span(Line(Point(1, 2), Point(4, 6))))
  println(span(Line(Point(0, 0), Point(2, 5))))

Key points

  • Nested pattern: a pattern inside another pattern, such as a case class inside a list pattern.
  • Use a nested pattern to reach a value deep inside a structure without a second match.
  • Each level of the pattern must match, or the whole case fails and the next case is tried.
  • A nested pattern can bind names at every level at once.
  • Keep nesting shallow, so one case stays easy to read.

In this example, span matches a line and both of its points in one case. It binds all four coordinates at once. The two lines prove the same nested pattern works for different lines.

Note

a nested pattern still needs a case for every shape it may meet, or a catch-all for the rest.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

What does List(Point(2, 3)) match with case Point(x, y) :: Nil => x * y and case _ => 0 give, where Point has fields x and y?