This question is essentially a duplicate of Debugging infinite loops in Haskell programs with GHCi. The author there solved it manually, though I'd like to know other solutions.
(my particular problem)
I have an arrow code which contains a recursive invocation,
testAVFunctor = proc x -> do
y <- errorArrow "good error" -< x
z <- isError -< y
(passError ||| testAVFunctor) -< trace "value of z" z
The errorArrow
should make the recursive testAVFunctor not execute, since that will cause isError to return a Left (AVError "good error")
which should in turn choose the passError
route and bypass the recursive call.
The very odd thing is that inserting "trace" calls at popular sites like the function composition results in the program emitting a finite amount of output, then freezing. Not what I'd expect from an infinite term expansion problem. (see edit 1)
I've uploaded my source code here if anyone is so curious.
EDIT 1
I wasn't looking in the right place (if you care to look at the source, apparently avEither was looping). The way I got there was by compiling a binary, and running gdb:
- gdb Main
- r (runs code)
- Ctrl+C (send interrupt). The backtrace will be useless, but what you can do, is hit
- s (step). Then, hold down the enter key; you should see a lot of method names fly by. Hopefully one of them will be recognizable.
You can compile with ghc flag -O0
to disable optimization, which can reveal more method names.
EDIT 3
Apparently, the proc x -> do
block above was causing the code to generate combinators, which were calling the AVFunctor.arr
lifting method to be called -- something in there must be violating laziness. If I rewrite the top level function as
testAVFunctor = errorArrow "good error" >>>
isError >>> (passError ||| testAVFunctor)
then everything works fine. I guess it's time to try learning and using garrows (by a grad student here at Berkeley).
My general takeaway from the experience is that ghci debugging can be frustrating. For example, I managed to make the argument f
of AVFunctor.arr
show up as a local variable, but I can't get anything terribly informative from it:
> :i f
f :: b -> c -- <no location info>
Revised source code is here