Extractors:
There are two methods used for extractors, unapply and unapplySeq. These are used in multiple variable assignments and pattern matching.
- The first use case is where unapply takes the object it is supposed to match and returns a - Booleanbased on whether or not it matches, for example,
 - trait Gender
trait Male extends Gender
trait Female extends Gender
object Male extends Male
object Female extends Female
class Person(val g: Gender, val age: Int)
object Adult {
    def unapply(p: Person) = p.age >= 18
}
def check(p: Person) = p match {
    case Adult() => println("An Adult")
    case _ => println("A Child")
}
//Will print: An Adult since Adult.unapply returns true.
check(new Person(Female, 18))
//Will print: A Child as it falls through to the _ case.
check(new Person(Male, 17))
 
Honestly, I don't really get the purpose of the above syntax since it can be done almost just as easily by just putting the code in the case statements. Of course if you have a better example, leave a comment below
- The general case where - unapplytakes some fixed-number of parameters and returns either an- Option[T]for a single parameter or a- Option[(p1,p2,...)]for multiple, i.e. a Tuple with the matched values, for example, continuing from the above code:
 - object Person {
    def apply(g: Gender, age: Int) = new Person(g, age)
    def unapply(p: Person) = if(p.age < 0) None else Some((p.g, p.age))
}
//Using Person.apply as described in the Basics section
val alice = Person(Female, 30)
val bob = Person(Male, 25)
//This calls Person.unapply(alice), which returns Some((Female, 30)).
//alice_gender is assigned Female and alice_age 30.
val Person(alice_gender, alice_age) = alice
bob match {
    //Calls Person.unapply(bob), but sees that g is Male, so no match.
    case Person(Female, _) => println("Hello ma'am")
    //Calls Person.unapply(bob) and assigns age = bob.age, but it doesn't pass
    //the 'if' statement, so it doesn't match here either.
    case Person(Male, age) if age < 18 => println("Hey dude")
    //So bob falls through to here
    case _ => println("Hello Sir")
}
Person(Male,-1) match {
    //Person.unapply(Person.apply(Male,-1)) returns None because p.age < 0.
    //Therefore this case will not match.
    case Person(_, _) => println("Hello person")
    //Thus it falls through to here.
    case _ => println("Are you Human?")
}
 
Note: Case classes do all those apply/unapply definitions for you (as well as other stuff) so use them whenver possible to save time and reduce code.
- unapplySeq. This works similarly to- unapplyas above, except it must return an- Optionof some kind of sequence.
As a quick example,
scala> List.unapplySeq(List(1,2,3))
res2: Some[List[Int]] = Some(List(1, 2, 3))