Mike Slinn

Enumerations

— Draft —

Published 2014-09-17. Last modified 2024-08-12.
Time to read: 2 minutes.

Enums are useful for expressing a finite number of items in a set in a symbolic manner. Enums allow your code to match against all possibilities, and to be able to verify that each possibility has been accounted for.

Scala 3 incorporates enums into the language. While you can use Scala 2 techniques for enums with Scala 3, you might want to use Scala 3 enums instead.

Scala 2 does not have an enum language construct, but you can use Java enums in Scala code. You have several other options for implementing enums when writing Scala 2. With the improvements made in Scala 2.11, and a little-known secret that I'll tell you about, the best option is now so good there is no reason to consider any other options.

The Scala 2 sample code for this lecture can be found in courseNotes/src/main/scala-2/Enums.scala.

The Scala 3 sample code for this lecture can be found in courseNotes/src/main/scala-3/Enums.scala.

Java enums

Java enums are efficient, compatible with both Java and Scala, extremely flexible and expressive. They are written in Java, however, and if you don’t know Java this can be awkward. If Java interoperability is important to you, this is probably your best option for providing enums to your Scala program because the Java enum values are authorative.

As we learned earlier in this course, you can mix Java source files and Scala source files in the same program. Whereas Scala source files are found in an SBT project under src/main/scala, Java programs are found under src/main/java. Here is an example Java enum stored in a file called src/main/java/Day.java. It is similar to Java 8’s DayOfWeek enum.

Java code
public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

Notice the Java convention is to write enum values in all upper case.

We can reference this Java code in the Scala 2 and Scala 3 REPLs. Note that the sbt console is used, which causes all of the courseNotes/ code to be compiled and loaded into the REPL:

SBT REPL
scala> sbt console
... lots of output ...
scala>
val day = Day.MONDAY monday: Day = MONDAY
scala>
if (day==Day.TUESDAY) println("Wimpy wants a hamburger")
scala> Day.valueOf("MONDAY") res20: Day = MONDAY
scala>
Day.values foreach { println } SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY

Ordered Java enums

Enum value sets will be discussed in the Sorting and Ordered Collections lecture of the Intermediate Scala course, but the bottom line is this: if you import the following then Java enums can be compared:

This Scala import allows Java enums to be compared
import scala.math.Ordering.Implicits._

With the above import, you can write comparative expressions involving Java enums, like this:

Scala code
def isWeekDay(day: Day) = day>=Day.MONDAY && day<=Day.FRIDAY
if (isWeekDay(Day.WEDNESDAY)) println("Waiting for weekend")

match Statements

Moving on, let’s use a Java enum in a match statement.

Scala REPL
scala> def tellItLikeItIs(theDay: Day): Unit = {
     |     val msg = theDay match {
     |     case MONDAY => "Mondays are bad."
     |     case FRIDAY => "Fridays are better."
     |     case SATURDAY => "Weekends are best."
     |     case SUNDAY => "Weekends are best."
     |     case _ => "Midweek days are so-so."
     |   }
     |   println(msg)
     | }
     tellItLikeItIs: (theDay: Day)Unit
scala>
tellItLikeItIs(MONDAY) Mondays are bad.
scala>
tellItLikeItIs(TUESDAY) Midweek days are so-so.
scala>
tellItLikeItIs(FRIDAY) Fridays are better.
scala>
tellItLikeItIs(SUNDAY) Weekends are best.

The Scala compiler has enforced exhaustive pattern matching on Java enums since Scala 2.10.

Shell
$ sbt console
... lots of output...
scala>
def whichDay(day: Day): String = day match { | case Day.MONDAY => "Monday" | } <console>:7: warning: match may not be exhaustive. It would fail on the following inputs: FRIDAY, SATURDAY, SUNDAY, THURSDAY, TUESDAY, WEDNESDAY def whichDay(day: Day) = day match { ^ whichDay: (day: Day)String

To get rid of the error, provide a catch-all case:

def whichDay(day: Day): String = day match {
  case Day.MONDAY => "Monday"
  case _ => "Every day"
}

* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.