Scala: Case class unapply vs a manual implementation and type erasure

I cannot give a complete answer, but I can tell you that even though the compiler generates an unapply method for case classes, when it pattern matches on a case class it does not use that unapply method. If you try -Ybrowse:typer using both builtin case matching and your unapply method, you will see a very different syntax tree is produced (for the match) depending on which is used. You can also browse the later phases and see that the difference remains.

Why Scala does not use the builtin unapply I am not sure, though it may be for the reason you bring up. And how to get around it for your own unapply I have no idea. But this is the reason Scala seems to magically avoid the problem.

After experimenting, apparently this version of unapply works, though I'm a bit confused about why:

def unapply[A,B](value: BlackOrWhite[A,B]): Option[B] = value match {
    case w: White[_,_] => Some(w.right)
    case _ => None
}

The difficulty with your unapply is that somehow the compiler has to be convinced that if a White[A,B] extends a BlackOrWhite[C,D] then B is the same as D, which apparently the compiler is able to figure out in this version but not in yours. Not sure why.


I can't give you the answer on the difference between case class match and unapply. However in their book (Odersky, Spoon, Venners) "Programming in Scala" 2nd chptr 26.6 "Extractors versus case classes" they write:

"they (case classes) usually lead to more efficient pattern matches than extractors, because the Scala compiler can optimize patterns over case classes much better than patterns over extractors. This is because the mechanisms of case classes are fixed, whereas an unapply or unapplySeq method in an extractor could do almost anything. Third, if your case classes inherit from a sealed base class, the Scala compiler will check our pattern matches for exhaustiveness and will complain if some combination of possible values is not covered by a pattern. No such exhaustiveness checks are available for extractors."

Which says to me that the two are more different than one would expect at first glance, however without being specific on what the exact differences are.