Explain the role of unapply methods in Scala's pattern matching.
Instruction: Discuss how the unapply method works in Scala's pattern matching, including examples.
Updated
An extractor's unapply recognizes a value and can provide components for a pattern. It need not be the inverse of an apply constructor; an object may define an extractor without defining construction at all.
final class Person(val name: String, val age: Int)
object Adult {
def unapply(person: Person): Option[String] =
if (person == null || person.age < 18) None
else Option(person.name)
}
def greeting(person: Person): String = person match {
case Adult(name) => s"Hello, $name"
case _ => "No adult name available"
}
@main def extractorExample(): Unit = {
assert(greeting(new Person("Ada", 30)) == "Hello, Ada")
assert(greeting(new Person("Lin", 17)) == "No adult name available")
assert(greeting(null) == "No adult name available")
}
Here Some(name) makes the pattern succeed and binds the extracted name; None makes it fail. The rule is only age at least 18 with a non-null name; it does not validate a person's identity or the plausibility of the supplied age. Extractor objects
Case classes provide extractor support automatically. Custom extractors can return multiple components, and a Boolean extractor can express recognition without bindings. Variable-length patterns use unapplySeq with the appropriate return protocol, rather than assuming an arbitrary Seq return from unapply has that meaning.
Keep recognition predictable and preferably side-effect-free. Exceptions thrown by an extractor do not automatically become a failed match, and evaluation may occur as pattern alternatives are tried. A fallback case handles non-matches; it does not make the extractor's implementation pure or safe.