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:
tt :: Show a => a -> a
tt x = trace (show x) x
So you surround your expressions with it and see there values, when those values get evaluated of course. Eg: myParser = (\_ code -> tt code) <$> parseComment <*> parseCodeNote: 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:
myfun a b | trace ("myfun " ++ show a ++ " " ++ show b) False = undefined
myfun a b = ...
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.
* `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.