The implementation is just something like
addIOErrorLocAndPath loc path io = catch io (\err -> ioError err{loc=loc,path=path})
This reminds me of _scc_:
1) We're annotating the code with programmer-meaningful annotations which are then used at runtime to help them understand program behaviour.
2) It has the same nested behaviour as _scc_
3) Just as stacks of cost centres are useful for profiling, it'd be useful to have stacks of error locations. When you print an IOError, you'd get a list of (nested) error locations - it'd feel a lot like the stack dumps you get from Java.
Right, but there's another issue here: we don't particularly want to expose the names of functions in the innards of the I/O library when we generate an IOError. The only piece of information that it of any use to a consumer of the library is the function that he/she called. The full stack trace is of course highly useful when debugging a library, though. In GHC, you *can* get the stack trace info when an exception is raised - you have to compile the program with profiling and -auto-all, and then run it with +RTS -xc (I think). We've also considered having a programatic interface to enable the CCS to be captured and treated as a first class object in Haskell, but we haven't got around to implementing it yet. Cheers, Simon