- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
A Tour of Scala: Extractor Objects
Created by admin on 2008-07-05.
Updated: 2008-12-21, 01:04
In Scala, patterns can be defined independently of case classes. To this end, a method named unapply
is defined to yield a so-called extractor.
For instance, the following code defines an extractor object Twice
.
object Twice { def apply(x: Int): Int = x * 2 def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None } object TwiceTest extends Application { val x = Twice(21) x match { case Twice(n) => Console.println(n) } // prints 21 }
There are two syntactic conventions at work here:
- The pattern
case Twice(n)
will cause an invocation ofTwice.unapply
, which is used to match even number; the return value of theunapply
signals whether the argument has matched or not, and any sub-values that can be used for further matching. Here, the sub-value isz/2
- The
apply
method is not necessary for pattern matching. It is only used to mimick a constructor.val x = Twice(21)
expands toval x = Twice.apply(21)
.
The return type of an unapply
should be chosen as follows:
- If it is just a test, return a
Boolean
. For instancecase even()
- If it returns a single sub-value of type
T
, return aOption[T]
- If you want to return several sub-values
T1,...,Tn
, group them in an optional tupleOption[(T1,...,Tn)]
.
Sometimes, the number of sub-values is fixed and we would like to return a sequence. For this reason, you can also define patterns through unapplySeq
. The last sub-value type Tn
has to be Seq[S]
. This mechanism is used for instance in pattern case List(x1, ..., xn)
.
Extractors can make code more maintainable. For details, read the paper "Matching Objects with Patterns" (see section 4) by Emir, Odersky and Williams (January 2007).