Expose srcLoc from the assertion architecture to allow better error messages
Assertions give great error messages by including file name and line, but they are disabled for optimisation. While there is a compiler flag to turn them on even in presence of optimisation, this is an awkward external way to simply attach a useful error location to something like
It would be great if we could decouple getting the current
srcLoc from assertions, and making it available for good error messages.
It is currently possible to do this using TemplateHaskell (e.g. the
placeholders package) or
CPP, but both are inconvenient for technical reasons (such as breaking tooling) and do not enjoy widespread use.
It seems a shame that the architecture for annotated error messages is already there, but only available through a mechanism that is disabled for optimisation (or at least "intended" to be disabled for optimisation).
Notably, we have the same architecture available for pattern mach failures:
f x | x > 0 = "foo" main = putStrLn (f (-1)) -- gives srcLoc'd pattern match error message
f x | x > 0 = "foo" f _ = error "f needs a positive number" main = putStrLn (f (-1)) -- does not give a srcLoc'd error message
It seems non-sensical that your try to write a better error message (here using
error) yields in fact a less-helpful error message.
I completely agree that one can aid bug-fixing by writing globally unique arguments to
error or using TH, but from an engineering perspective, a little bit of help from the language/compiler side can improve the situation a lot, and in other languages this is acknowledged and used to everybody's benefit.
There are some alternatives we might consider, such as
srcLoc :: Stringthat gives an
assert-style location at the lexical position of its occurrence
- adding an
error-like function that behaves like
errorbut also prints a source location
srcLoc :: String breaks equational reasoning on the syntactic level, as
let x = srcLoc in (x, x) and
(srcLoc, srcLoc) have different values. However, looking at it from a program execution point of view, referential transparency is preserved since once compiled, any function using
srcLoc will always return the same location.
I believe that offering some kind of improvement over the dreaded
Prelude: undefined should be easy to implement, but let's hear what the people who actually know the compiler think about it.