
Aw, that is really suboptimal. Have you filed a bug? Edward Excerpts from Michael Snoyman's message of Thu Jan 19 23:29:59 -0500 2012:
On Fri, Jan 20, 2012 at 5:23 AM, Edward Z. Yang
wrote: Oh, I'm sorry! On a closer reading of your message, you're asking not only asking why 'fail' was added to Monad, but why unfailable patterns were removed.
Well, from the message linked:
In Haskell 1.4 g would not be in MonadZero because (a,b) is unfailable (it can't fail to match). But the Haskell 1.4 story is unattractive becuase a) we have to introduce the (new) concept of unfailable b) if you add an extra constructor to a single-constructor type then pattern matches on the original constructor suddenly become failable
(b) is a real killer: suppose that you want to add a new constructor and fix all of the places where you assumed there was only one constructor. The compiler needs to emit warnings in this case, and not silently transform these into failable patterns handled by MonadZero...
But wait a second... this is exactly the situation we have today! Suppose I write some code:
data MyType = Foo
test myType = do Foo <- myType return ()
As expected, no warnings. But if I change this "unfailable" code above to the following failable version:
data MyType = Foo | Bar
test myType = do Foo <- myType return ()
I *still* get no warnings! We didn't make sure the compiler spits out warnings. Instead, we guaranteed that it *never* will. This has actually been something that bothers me a lot. Whereas everywhere else in my pattern matching code, the compiler can make sure I didn't make some stupid mistake, in do-notation I can suddenly get a runtime error.
My opinion is we should either reinstate the MonadZero constraint, or simply can failable pattern matches.
Michael