Бесконечная рекурсия в Haskell

Этот вопрос, по сути, дублирует Отладка бесконечных циклов в программах Haskell с помощью GHCi . Автор решил это вручную, хотя я хотел бы знать другие решения .

(моя конкретная проблема)

У меня есть код стрелки, который содержит рекурсивный вызов,

testAVFunctor = proc x -> do
    y <- errorArrow "good error" -< x
    z <- isError -< y
    (passError ||| testAVFunctor) -< trace "value of z" z

errorArrow должен заставить рекурсивный testAVFunctor не выполняться, поскольку это вызовет isError чтобы вернуть Left (AVError "хорошая ошибка" ) , который, в свою очередь, должен выбрать маршрут passError и обойти рекурсивный вызов.

Очень странно то, что вставка вызовов "трассировки" на популярных сайтах, таких как композиция функций, приводит к тому, что программа генерирует конечный объем вывода, затем замораживание. Не то, что я ожидал бы от задачи бесконечного расширения. (см. правку 1)

Я загрузил свой исходный код сюда , если кому-то интересно.

РЕДАКТИРОВАТЬ 1

Я искал не в том месте (если вам интересно посмотрите на источник, видимо avEither зацикливался). Я добился этого путем компиляции двоичного файла и запуска gdb :

  • gdb Main
  • r (запускает код)
  • Ctrl + C (отправка прерывания) . Обратный след будет бесполезен, но что вы можете сделать, попадет
  • с (шаг) . Затем нажмите и удерживайте клавишу ввода; вы должны увидеть много имен методов. Надеюсь, один из них будет узнаваемым.

Вы можете скомпилировать с флагом ghc -O0 , чтобы отключить оптимизацию, которая может показать больше имен методов.

РЕДАКТИРОВАТЬ 3

По-видимому, Блок proc x -> do , приведенный выше, заставлял код генерировать комбинаторы, которые вызывали метод подъема AVFunctor.arr , который должен быть вызван - что-то там должно быть нарушает лень. Если я перепишу функцию верхнего уровня как

testAVFunctor = errorArrow "good error" >>>
    isError >>> (passError ||| testAVFunctor)

, все будет работать нормально. Думаю, пора попробовать изучить и использовать garrows (аспирантом здесь, в Беркли).

Мой общий вывод из опыта состоит в том, что отладка ghci может вызывать разочарование. Например, Мне удалось сделать так, чтобы аргумент f из AVFunctor.arr отображался как локальная переменная, но я не могу получить от него ничего ужасно информативного:

> :i f
f :: b -> c     -- 

Исправленный исходный код здесь

5
задан Community 23 May 2017 в 10:24
поделиться