
On Fri, Jan 20, 2012 at 5:23 AM, Edward Z. Yang
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