I have had some success stuffing a ReaderT [String] in my monad stack to create traces with a custom flow using:
local ("a tag for the code block":) $ BLOCK.
The idea is that when a mistake is detected you read the trace and throw that along with whatever error information is available. It is a lot better than printing stuff, because it is independent of evaluation order, and follows the structure of your monadic code.
It is quite easy to set up and use. It is really just two functions and an extra level in the monad stack.
It is quite easy to set up and use. It is really just two functions and an extra level in the monad stack.