Scala Enumerations hell

Motivation

Should you use Scala’s built-in scala.Enumeration class or write your own implementation based on sealed class objects? People have been talking about it forever. But almost everyone agrees that usage of scala.Enumeration leaves a very bad taste and furthermore, it has few major problems.

1. Method overloading

If you want to overload a method with different scala.Enumeration, that’s not going to work:

2. Pattern matching

In Scala we heavily rely on the compiler powerful type system, but if you want to use scala.Enumeration in pattern matching, you won’t get a “match may not be exhaustive” warning:

3. NoSuchElementException

To get a scala.Enumeration instance by name, Scala’s API provides method withName with following signature:

If there is no Value with a matching name in the Enumeration, it throws a NoSuchElementException, which is not described in the method definition. So you always should wrap it in a Try.

4. Extra fields

There is no way to add extra fields to scala.Enumeration instances:

Sealed case objects

With sealed case objects, we can solve all problems above.

With this approach, the compiler is able to detect non-exhaustive pattern matching, avoid type erasure problems and also add extra fields to enum’s instances.

What we still need to do is to provide a possibility to get a set of all enum’s values and find an enum by name. It can be done with Scala’s reflection API:

In the end, we have the following code:

Conclusion

Obliviously, enumerations in Scala are massive pain, but a set of sealed case objects give us a good way to represent them. Also, a new kind of enum class will be released in Dotty with all described features.