Scala Enumerations hell
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:
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
4. Extra fields
There is no way to add extra fields to
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:
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.