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

Gregory Crosswhite gcrosswhite at gmail.com
Fri Jan 20 03:47:42 CET 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).  :-)


More information about the Haskell-Cafe mailing list