Подтвердить что ты не робот

Поиск, где произошел << цикл >>

Если мы получим a <<loop>>, это означает, что Haskell удалось обнаружить бесконечный цикл. Есть ли способ заставить ghc рассказать нам, где произошел этот цикл? Кажется, что Haskell должен иметь эту информацию где-то.

4b9b3361

Ответ 1

Скомпилируйте приложение с помощью -prof и -fprof-auto (если вы используете Cabal, используйте --enable-executable-profiling и --ghc-options=-fprof-auto), а затем запустите его с помощью +RTS -xc. Он будет печатать трассировку стека при возникновении ошибок. Это должно помочь вам сузить область действия.

Пример:

➜  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>>

Ответ 2

В дополнение к тому, что уже было написано: эти циклы обнаруживаются только во время выполнения. Обнаружение основано на коде, пытающемся оценить значение, которое уже оценивается [по тому же потоку]. Ясно, что этого никогда не должно быть.

Если вы ищете компилятор, чтобы обнаружить это во время компиляции... вам не повезло. Это достаточно легко, чтобы статически определить рекурсию, но решить, является ли рекурсия бесконечной или нет, не так просто.