Personally, I've been spending a lot of my recent time trying to debug a Parsec parser (it seems to be going into loops of backtracking, but I can't figure out where and why), and it's been a clusterfuck.
* `trace` and `traceM` don't actually get evaluated, so I can't use printing to find my bugs.
* Even putting `trace "..." True` as a guard to my parser combinators doesn't seem to actually print anything.
* `seq` and `deepseq` require that I implement all kinds of instances for datatypes whose innards I can't actually access, so I can't force the evaluation.
* I'm getting tempted to use `unsafePerformIO` just to get some damn debug output, but can't figure out how to make it have the right type inside the Parsec monad.
Debugging Haskell sucks when you need to debug dynamic behavior rather than type errors.
Comments
Personally, I've been spending a lot of my recent time trying to debug a Parsec parser (it seems to be going into loops of backtracking, but I can't figure out where and why), and it's been a clusterfuck.
* `trace` and `traceM` don't actually get evaluated, so I can't use printing to find my bugs.
* Even putting `trace "..." True` as a guard to my parser combinators doesn't seem to actually print anything.
* `seq` and `deepseq` require that I implement all kinds of instances for datatypes whose innards I can't actually access, so I can't force the evaluation.
* I'm getting tempted to use `unsafePerformIO` just to get some damn debug output, but can't figure out how to make it have the right type inside the Parsec monad.
Debugging Haskell sucks when you need to debug dynamic behavior rather than type errors.
Note that trace is implemented in terms of unsafePerformIO (which is fine for debugging).
To get a trace message, you need to attach the trace to something that does get evaluated. I mostly define a somewhat simpler helper like this:
So you surround your expressions with it and see there values, when those values get evaluated of course. Eg:Note: I just looked at the docs linked in creichert's sibling post, and I noticed that Debug.Trace provides traceShow as a helper.
Using the trace trick needs to guard on False:
See here for some other helpful trace functions:https://hackage.haskell.org/package/base-4.8.1.0/docs/Debug-...
There is even a traceStack which will print a call stack if available.