Finding where <<loop>> happened
If we get a <<loop>>, it means that Haskell had managed to detect an infinite loop. Is there a way to get ghc to tell us where this loop happened? It seems that Haskell should have this information somewhere.
Compile your app with -prof and -fprof-auto(if you're using Cabal, use --enable-executable-profiling and --ghc-options=-fprof-auto) and then run it with +RTS -xc. It'll print a stack trace when errors happen. This should help you narrow your scope.
➜ haskell cat loop.hs myFun :: Int myFun = let g = g + 1 in g + 10 main = print myFun ➜ haskell ghc loop.hs -prof -fprof-auto [1 of 1] Compiling Main ( loop.hs, loop.o ) Linking loop ... ➜ haskell ./loop +RTS -xc *** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: Main.myFun.g, called from Main.myFun, called from Main.CAF *** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: Main.myFun.g, called from Main.myFun, called from Main.CAF loop: <<loop>>
In addition to what has already been written: These loops are only detected at run-time. The detection is based on the code attempting to evaluate a value which is already being evaluated [by the same thread]. Clearly that should never happen.
If you're looking for a compiler switch to detect this at compile-time... you're out of luck. It's easy enough to statically spot recursion, but deciding whether the recursion is infinite or not isn't so easy.