Я нахожусь в середине долгого сеанса отладки, чтобы найти причину бесконечного цикла.Я очень близко, и это то, что помогло мне больше всего.Предположим, что ваш цикл вызван чем-то вроде этого:
...
x1 = f1 x2 y
x2 = f2 z x3
x3 = f3 y x1
...
Итак, x1 зависит от x2, который зависит от x3, который зависит от x1.ПЛОХО!
Посыпать следовые функции в определениях f1, f2, f3.Что-то вроде:
f1 x y | trace ("f1: ") False = undefined
f1 x y = ... -- definition of f1
f2 x y | trace ("f2: ") False = undefined
f2 x y = ... -- definition of f2
-- same for f3
Запустите вашу программу, чтобы увидеть, какая из этих функций вызывается.Вывод может быть примерно таким:
f3:
f2:
f1:
<<loop>>
Затем начните показывать некоторые переменные в функциях трассировки.Например, если вы измените след f2 на
f2 x y | trace ("f2: x: " ++ show x) False = undefined
, то результат будет выглядеть примерно так:
f3:
f2: x: x_value
f1:
<<loop>>
Но если вы затем измените след f2 на
f2 x y | trace ("f2: x: " show x ++ " y: " ++ show y) False = undefined
Тогда результат будет
f3:
<<loop>>
, поскольку второй аргумент f2 не может быть оценен из-за циклической зависимости.
Итак, теперь вы знаете, что один изфункции в бесконечном цикле - это f2, а второй аргумент (но не первый) имеет круговую зависимость.
Счастливая отладка!