ADTs let the compiler prove you've handled every case, eliminating whole classes of bugs.
An algebraic data type (ADT) is a type defined as one of a fixed set of alternatives, each possibly carrying data. Scala 3's enum expresses them directly:
- A simple enumeration:
enum Color { case Red, Green, Blue }withColor.values,Color.valueOf("Red")andordinal. - Enums can have parameters and members:
enum Planet(val mass: Double) { case Earth extends Planet(5.97e24) ... }. - Cases can carry their own data, making a full ADT:
enum Shape { case Circle(r: Double); case Rect(w: Double, h: Double) }. - Enums can be generic: the standard
Optioncould be writtenenum Option[+A] { case Some(x: A); case None }.
The equivalent in Scala 2 style, still common and sometimes more flexible, is a sealed trait with case class and case object subtypes in the same file.
Because the set of cases is closed, a match that misses one produces a compiler warning ("match may not be exhaustive"). Treat it as an error (-Werror) and you get a compile-time checklist whenever a new case is added.
Design tip: make illegal states unrepresentable. Instead of a class with nullable fields and a status string, define an enum where each case has exactly the data that state needs.
Example
enum Color:
case Red, Green, Blue
enum Payment:
case Card(number: String, expiry: String)
case Transfer(iban: String)
case Cash
import Payment.*
def fee(p: Payment, amount: Double): Double = p match
case Card(_, _) => amount * 0.02
case Transfer(_) => 0.5
case Cash => 0.0
// removing a case gives: "match may not be exhaustive"
@main def enums(): Unit =
println(Color.values.toList) // List(Red, Green, Blue)
println(Color.valueOf("Green").ordinal) // 1
val payments = List(Card("4242", "12/29"), Transfer("AM00"), Cash)
println(payments.map(fee(_, 100))) // List(2.0, 0.5, 0.0)
println(Transfer("X")) // Transfer(X)Remember
enummodels a closed set of cases, with or without data- Sealed traits plus case classes are the equivalent older encoding
- Exhaustiveness checking warns when a case is missing
- Make illegal states unrepresentable
Watch out for
- Adding a wildcard
case _to every match, which silences exhaustiveness warnings when new cases are added.