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

Edward Z. Yang ezyang at MIT.EDU
Fri Jan 20 04:23:28 CET 2012

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

(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...


Excerpts from Gregory Crosswhite's message of Thu Jan 19 21:47:42 -0500 2012:
> Today I learned (tldr; TIL) that the "fail" in the Monad class was added
> as a hack to deal with the consequences of the decision to remove
> "unfailable" patterns from the language.  I will attempt to describe the
> story as I have picked it up from reading around, but please feel free
> to correct me on the details.  :-)
> An "unfailable" pattern (which is a generalization of an "irrefutable"
> pattern) is a pattern which can never fail (excluding the possibility of
> _|_), such as
>     let (x,y) = pair
> Before "fail" was a method of the Monad class, using refutable patterns
> in a monad required the type to be an instance of MonadZero (that is,
> MonadPlus without the plus), so that for example
>     do Just x <- m
> required that the monad be an instance of MonadZero.  If you avoided
> such patterns, your Monad did not have to have this instance, so that
> for example
>     do (x,y) <- pair
> would not require MonadZero because the pattern is unfailable.
> To me this seems like a lovely way of handling the whole matter, and
> much improved over the incredibly ugly wart of having a "fail" method in
> the Monad class.  In fact, I think I remember people on this list and in
> other forums occasionally bringing something like this approach up as a
> way of getting rid of the "fail" wart.
> So my question is, why did we go to all of the trouble to transition
> away from the MonadZero approach to the current system to begin with? 
> What was so bad about "unfailable" patterns that it was decided to
> remove them and in doing so replace MonadZero with a mandatory "fail"
> method in Monad?  I mean, this *is* Haskell, so my safest assumption is
> that smart people were involved in making this decision and therefore
> the reasons much have been really good (or at least, seemed good given
> the information at the time).  :-)
> Cheers,
> Greg

More information about the Haskell-Cafe mailing list