[Haskell-cafe] Why were unfailable patterns removed and "fail" added to Monad?

Michael Snoyman michael at snoyman.com
Fri Jan 20 05:29:59 CET 2012

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

My opinion is we should either reinstate the MonadZero constraint, or
simply can failable pattern matches.


More information about the Haskell-Cafe mailing list