The main reason to seal classes seems to be that this allows the compiler to do exthaustivity searches when pattern matching on those classes. Say I have data types meant for pattern matching. Toy example:
sealed trait Statement
case class Assign(name: String, value: Int) extends Statement
case class Print(name: String) extends Statement
case class IfZero(name: String, thenn: Statement, els: Option[Statement]) extends Statement
case class Block(statements: List[Statement]) extends Statement
The use case for these classes would be to consume them through pattern matching:
def execute(statement: Statement): Unit = statement match {
case Assign(name, value) => ???
case Print(name) => ???
case IfZero(name, thenn, els) => ???
case Block(statements) => statements foreach { execute(_) }
}
To this end, the Statement
trait is sealed
so that the compiler can warn me if I forget one statement kind in the match statement. But what about the case classes? Case classes cannot inherit from each other, but traits and ordinary classes can. So, is it good practice to seal the case classes as well? What could go wrong if I don't?