[Haskell-cafe] Printing call site for partial functions

Michael Snoyman michael at snoyman.com
Wed Apr 25 17:36:28 CEST 2012

I had a bug in a site of mine[1] for a few weeks, where it would just print:

    Prelude.head: empty list

It took a long time to track down the problem, as it came from some
other library I was depending on. Eventually I tracked it down,
reported it, and the problem was fixed the next day. The weak link in
this chain was identifying what package was to blame.

I noticed the other day that the docs for undefined[2] state:

> It is expected that compilers will recognize this and insert error messages which are more appropriate to the context in which undefined appears.

I'm not sure if the current output of `Prelude.undefined` is meant to
fit the criterion of "appropriate to the context", but in my opinion
it does not. I'd like to propose a bit of a strawman to improve the
situation for not just `undefined`, but any arbitrary partial function
(including `head`). What we really want is to define some function

    headContext :: String -> [a] -> a
    headContext context [] = error $ "Prelude.head: empty list (" ++
context ++ ")"
    headContext _ (x:_) = x

And then have the compiler automatically include (optional) package
name, module name, and line number where `headContext` was called. How
about we borrow a bit from rewrite rules, and have a pragma such as:

    {-# WITH_CONTEXT head headContext #-}

If the compiler supports the feature, and is able to provide context
in the given location, it will call `headContext` with an appropriate
`String`. Otherwise, normal `head` would be called.

I'm sure there are many better ways to approach the problem, and I
can't speak to the complexity of implementation within GHC. I *can*
say, however, that this would have saved me a lot of time in the
example I gave above, and I'd bet many Haskellers have similar
stories. This could be a huge debugging win across the board.


[1] It was actually yesodweb.com, and resulted in empty Javascript
files being generated, thus disabling some features of the site.
[2] http://hackage.haskell.org/packages/archive/base/

More information about the Haskell-Cafe mailing list