The answer has to do with in what ways the code is easy to extend, a tension between classes and algebraic data types that Phil Wadler dubbed "the expression problem":
So, algebraic data types are closed because a closed type supports certain kinds of program evolution well. For example, if your data types define a language, it is easy to add new compiler passes without invalidating old ones or changing the data.
It is possible to have "open" data types, but except under carefully controlled circumstances, the type checking becomes difficult. Todd Millstein did some very beautiful work on a language design that supports open algebraic types and extensible functions, all with a modular type checker. I found his paper a great pleasure to read.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…