🎓 A1Learner
🔍
0 of 48 lessons completed

Scala Extractors

An extractor is an object with an unapply method that pulls a value apart in a match. It lets a match test a value and bind a part of it in one step.

An extractor splits an even number

Even unapply returns Some of the half for an even number. The match binds that half to a name.

object Even:
  def unapply(n: Int): Option[Int] =
    if n % 2 == 0 then Some(n / 2) else None
@main def main(): Unit =
  val result = 10 match
    case Even(half) => half
    case _ => -1
  println(result)

None sends the match to the next case

For an odd number, unapply returns None. The catch-all case then runs.

object Even:
  def unapply(n: Int): Option[Int] =
    if n % 2 == 0 then Some(n / 2) else None
@main def main(): Unit =
  val result = 7 match
    case Even(half) => half
    case _ => 0
  println(result)

An extractor can split a string

A string extractor can split a name into two parts. The match binds both parts at once.

object Name:
  def unapply(s: String): Option[(String, String)] =
    val parts = s.split(" ")
    if parts.length == 2 then Some((parts(0), parts(1))) else None
@main def main(): Unit =
  val result = "Ada Lovelace" match
    case Name(first, last) => last + ", " + first
    case _ => "no"
  println(result)

Example

object Even:
  def unapply(n: Int): Option[Int] =
    if n % 2 == 0 then Some(n / 2) else None
def halve(n: Int): Int = n match
  case Even(half) => half
  case _ => -1
@main def main(): Unit =
  println(List(10, 7, 12).map(halve))

Key points

  • Extractor: an object whose unapply method turns a value into an Option of parts.
  • Use a pattern such as Even(half) to test a number and bind its half in one step.
  • A Some result means the pattern matches and its contents become the bound names.
  • A None result means the pattern does not match and the next case is tried.
  • Use an extractor for a test that a plain literal pattern cannot express.

In this example, halve matches each number against Even. Even numbers give their half, and the odd number falls through to -1. The mapped list shows all three results in order.

Note

unapply is a plain method, so it can hold any test that returns an Option.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

What does 8 match with case Even(half) => half and case _ => 0 give?