Better exception for non-exhaustive patterns in case

Is there a way to get GHCi to produce better exception messages when it finds at runtime that a call has produced value that does not match the function's pattern matching?

It currently gives the line numbers of the function which produced the non-exhaustive pattern match which though helpful at times does require a round of debugging which at times I feel is doing the same set of things over and over. So before I tried to put together a solution I wanted to see if something else exists.

An exception message that in addition to giving the line numbers shows what kind of call it attempted to make?

Is this even possible?


Try turning on warnings in ghci. This enables the compile time warnings you can get with ghc by passing -W, for example. You can do this several ways:

ghci -fwarn-incomplete-patterns

Or Neil Mitchell describes how he sets this up in his .ghci. Here is the relevant excerpt:

:set -fwarn-incomplete-patterns

You can manually enter this at ghci as well, but it would be a pain to do so each time you start it. Entered this way, it only works for statements entered at the prompt, not for loading files with :l. Instead you can put this comment at the top of the file you want to warn about incomplete patterns:

{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}

I recognize that this is something of a non-answer to your question, but my impression is that among veteran Haskell programmers there's a general consensus that non-exhaustive patterns should be avoided in the first place, even to the point of using -Werror to generate errors instead of just warnings.

I'm not sure how well that works in combination with GHCi, however, especially if you're writing functions at the prompt instead of loading a file--I can imagine it getting in the way more than it helps for working interactively. Running GHCi with the appropriate command-line flags seems to get the desired result for me, though.

If you want a more drastic solution to non-exhaustive patterns, you could always port Catch to work with modern GHC versions. Heh.

Beyond that, if you're using non-exhaustive patterns because the function really, truly, should never be called with some values, the missing cases can be filled in with something like error $ "function foo called with ridiculous arguments " ++ show blahBlah, if knowing the invalid arguments would be helpful. Alternately, you could try to rework your code or define more specialized data types such that functions can always do something sensible with any non-bottom argument.

Otherwise, I think you're stuck with awkward debugging.