I want to match on some case classes. If I don't know them, I want to match on a specified trait the classes have to extend. This looks like
trait Event //root trait
trait Status extends Event //special trait
trait UIEvent extends Event //special trait
case class Results extends Event //concrete case class
case class Query extends Event //concrete case class
case class Running extends Status //concrete case class
case class Finished extends Status //concrete case class
case class Update extends UIEvent //concrete case class
I run the following test
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 matched at all " + x)
}
println("############################")
val STATUS = classOf[Status]
val EVENT = classOf[Event]
val UIEVENT = classOf[UIEvent]
val RESULTS = classOf[Results]
val eventsClass = events map (_.getClass)
eventsClass foreach {
case RESULTS => println("Got a Results")
case STATUS => println("Got some StatusEvent")
case UIEVENT => println("Got some UIEvent")
case EVENT => println("Generic Event")
case x => println("Didn't matched at all " + x)
}
which leads to the following output
Got a Results
Didn't match at all Query
Got a Running
Didn't match at all Finished
Didn't match at all Update
############################
Didn't match at all class de.mukis.scala.test.main.Results$
Didn't match at all class de.mukis.scala.test.main.Query$
Didn't match at all class de.mukis.scala.test.main.Running$
Didn't match at all class de.mukis.scala.test.main.Finished$
Didn't match at all class de.mukis.scala.test.main.Update$
Why can't I pattern match on case class and traits or just only on the class?
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 object
s
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)
}