Scala Language Enumerations Using sealed trait and case objects


Example

An alternative to extending Enumeration is using sealed case objects:

sealed trait WeekDay

object WeekDay {
  case object Mon extends WeekDay
  case object Tue extends WeekDay
  case object Wed extends WeekDay
  case object Thu extends WeekDay
  case object Fri extends WeekDay
  case object Sun extends WeekDay
  case object Sat extends WeekDay
}

The sealed keyword guarantees that the trait WeekDay cannot be extended in another file. This allows the compiler to make certain assumptions, including that all possible values of WeekDay are already enumerated.

One drawback is that this method does not allow you to obtain a list of all possible values. To get such a list it must be provided explicitly:

val allWeekDays = Seq(Mon, Tue, Wed, Thu, Fri, Sun, Sat)

Case classes can also extend a sealed trait. Thus, objects and case classes can be mixed to create complex hierarchies:

sealed trait CelestialBody
    
object CelestialBody {
  case object Earth extends CelestialBody
  case object Sun extends CelestialBody
  case object Moon extends CelestialBody
  case class Asteroid(name: String) extends CelestialBody
}

Another drawback is that there is no way to access a the variable name of a sealed object's enumeration, or search by it. If you need some kind of name associated to each value, it must be manually defined:

  sealed trait WeekDay { val name: String }

  object WeekDay {
      case object Mon extends WeekDay { val name = "Monday" }
      case object Tue extends WeekDay { val name = "Tuesday" }
      (...)   
  }

Or just:

  sealed case class WeekDay(name: String)
    
  object WeekDay {
      object Mon extends WeekDay("Monday")
      object Tue extends WeekDay("Tuesday")
      (...)   
  }