Scala: Mix traits and case class in pattern match

Your problem is with case class without parantheses (which are now deprecated). A case class implies the creation of a companion object. When you write Results without parantheses, both in your list, and in the pattern matching, it means the companion object.

You may try

define sortOut(x: Any) = x match {
  case Results => "companion object"
  case Results() => "instance"
}

sortOut(Results) // returns companion object
sortout(Results()) // returns instance

This explains the behavior in the second part. As Results is the companion object, Results.getClass() is not classOf[Results], which is the class of instance, but the (synthetic) class of the companion object, Results$

If a case class has no parameters, most of the time it means that various instances cannot be distinguished from each other, and you should rather use a case object. Otherwise, put the parantheses.


The problem is that you're referring to the companion objects for your case classes, not specific instances of them. The REPL should already have supplied you with deprecation warnings due to this.

The solution is to add a few parentheses:

sealed abstract trait Event
sealed abstract trait Status extends Event
sealed abstract trait UIEvent extends Event

case class Results() extends Event
case class Query() extends Event

case class Running() extends Status
case class Finished() extends Status

case class Update() extends UIEvent

and

val events = List(Results(), Query(), Running(), Finished(), Update())
events foreach {
  case Results() => println("Got a Results")
  case Running() => println("Got a Running")
  case s:Status => println("Got some StatusEvent")
  case ui:UIEvent => println("Got some UIEvent")
  case e: Event => println("Generic Event")
  case x => println("Didn't match at all " + x)
}

or, as didierd suggests, use case objects

sealed abstract trait Event
sealed abstract trait Status extends Event
sealed abstract trait UIEvent extends Event

case object Results extends Event
case object Query extends Event

case object Running extends Status
case object Finished extends Status

case object Update extends UIEvent

and

val events = List(Results, Query, Running, Finished, Update)
events foreach {
  case Results => println("Got a Results")
  case Running => println("Got a Running")
  case s:Status => println("Got some StatusEvent")
  case ui:UIEvent => println("Got some UIEvent")
  case e: Event => println("Generic Event")
  case x => println("Didn't match at all " + x)
}