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?