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

Edward Z. Yang ezyang at MIT.EDU
Fri Jan 20 05:53:53 CET 2012


It's not obvious that this should be turned on by -Wall, since
you would also trigger errors on uses like:

    [ x | Just x <- xs ]

T_T

But I do think it ought to be an option.

Cheers,
Edward

Excerpts from Michael Snoyman's message of Thu Jan 19 23:52:10 -0500 2012:
> On Fri, Jan 20, 2012 at 6:41 AM, Edward Z. Yang <ezyang at mit.edu> wrote:
> > Aw, that is really suboptimal.  Have you filed a bug?
> 
> I think it's a feature, not a bug. When dealing with monads that
> provide nice[1] implementations of `fail`, you can (ab)use this to
> avoid writing a bunch of case expressions. I remember reading it in
> one of the first tutorials on Haskell I looked at (four years ago now?
> you can see how much this bothered me if I still remember that).
> 
> I admit that there are some use cases where the current behavior is
> convenient, but I think we're paying too steep a price. If we got rid
> of this feature entirely, we could (a) get rid of fail and (b) have
> the compiler warn us about a bunch of errors at compile time.
> 
> But maybe I should file a feature request: provide an extra warning
> flag (turned on by -Wall) that will warn when you match on a failable
> pattern. Essentially, I would want:
> 
> SomeConstr args <- someAction
> 
> to be interpreted as:
> 
> temp <- someAction
> case temp of
>     SomeConstr args ->
> 
> Michael
> 
> [1] For some people's definition of nice, not mine.
> 
> >
> > 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 <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
> >> error.
> >>
> >> My opinion is we should either reinstate the MonadZero constraint, or
> >> simply can failable pattern matches.
> >>
> >> Michael



More information about the Haskell-Cafe mailing list