| > b) if you add an extra constructor to a single-constructor type
| > then pattern matches on the original constructor suddenly become
| >failable
|
| That is great. I'd rather have this as a static error that getting an
| unexpected pattern match failure in my nuclear reactor device driver:
|
| data Position = Open | Close
| controlReactor = do{ .....; Open <- checkValve; ... }
|
| than have this fail silently using the default definition mfail =
| undefined.
I agree that this is an error that you would like the system to catch.
I disagree strongly with the suggestion that this is an error that you
should expect the *type system* to catch.
Suppose that the original version of your nuclear reactor driver also
contained a definition:
inCaseOfEmergency Open = ...
When an extra constructor is added to the datatype, you would hope that
your compiler might report a "non-exhaustive pattern match" error here,
alerting the programmer to the fact that modifications to this function
definition might be required. This isn't a type error, it's a question
about values within a type, and about whether you manage to cover all
the possibilities.
Likewise, your definition of controlReactor might reasonably be
expected to generate a "non-exhaustive pattern match" error when
the second constructor is added.
You'll be seriously misleading designers of nuclear reactor drivers,
as well as those for more mundane appliances, if you tell them that
Haskell's ability to raise a type error in situations like this will
make the language safer. For one thing, it only applies to do notation,
and not to pattern matches in function definitions. For another, it
wouldn't do anything to help in situations where a datatype with two
constructors is modified to add a third.
So here is good motivation for adding mechanisms to check for exhaustive
pattern matches, but not for choosing between the alternatives that
are being considered for do notation.
All the best,
Mark