ADTs & Enums in Scala 3: Making Illegal States a Compile Error
ADTs & Enums in Scala 3 If you've worked on enough business software, you've probably seen this: final case class Order ( status : String , paidAt : Option [ Instant ], shippedAt : Option [ Instant ], cancelReason : Option [ String ] ) It looks harmless. Until you realize that this type allows all of these: Order ( "pending" , Some ( now ), None , Some ( "customer changed their mind" )) Order (…
Final case classes in Scala often allow invalid combinations of fields. For example, an Order can have a paidAt timestamp even if it's not paid, a shippedAt timestamp even if it's not shipped, or a cancelReason even if it's not cancelled. The compiler has no way to catch these illegal states, leading to potential issues later on. Algebraic Data Types (ADTs) can help solve this problem by making those illegal combinations impossible to construct.
In Scala 3, enums provide a convenient way to model this as an ADT. For instance, an Order can be in one of four states: Pending, Paid, Shipped, or Cancelled. Each state has specific fields that must be present, and none of the fields are allowed in states where they don't make sense. The domain constraints are now represented by the type system, so an invalid state cannot exist in the first place. The compiler becomes part of your test suite, catching any attempts to create an invalid state.
Pattern matching can be used to summarize each state of the Order. If an order is in the Pending state, it's waiting for payment. If it's Paid, it has a paidAt timestamp. If it's Shipped, it has a shippedAt timestamp. And if it's Cancelled, it has a cancelReason. This makes the code more expressive and less prone to errors. If the business later decides to support refunded orders, adding a new case to the enum is straightforward. The compiler ensures that all valid states are covered, keeping the code clean and robust.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.