Посмотреть шаги сокращения в Haskell - PullRequest
14 голосов
/ 29 апреля 2009

Есть ли способ просмотреть шаги сокращения в haskell, то есть отследить выполненные рекурсивные вызовы функций? Например, схема chez предоставляет нам trace-lambda. Есть ли в Haskell эквивалентная форма?

Ответы [ 4 ]

7 голосов
/ 29 апреля 2009

Вы можете попробовать вставить Debug.Trace.trace в местах, которые вы хотите отследить, но это имеет тенденцию: (а) производить дикий выход из строя, поскольку ваш оператор трассировки может принадлежать thunk это не оценивается до тех пор, пока далеко от исходного вызова, и (б) изменение поведения вашей программы во время выполнения, если трассировка требует оценки вещей, которые иначе не были бы оценены (пока).

Это для отладки? Если так ...


Hat изменяет исходный код для вывода трассировки, которая может быть просмотрена после запуска. Вывод должен быть очень близок к тому, что вы хотите: пример на их домашней странице:

Например, вычисление неисправной программы

main = let xs :: [Int]
           xs = [4*2,5 `div` 0,5+6]
       in  print (head xs,last' xs)

last' (x:xs) = last' xs
last' [x] = x

дает результат

(8, No match in pattern.

и инструменты просмотра Hat можно использовать для изучения его поведения следующим образом:

  • Hat стек

Для прерванных вычислений, то есть вычислений, которые завершились с сообщением об ошибке или были прерваны, стек стека показывает, в каком вызове функции вычисление было прервано. Это достигается путем показа виртуального стека вызовов функций (переопределений). Таким образом, каждый вызов функции, показанный в стеке, вызывал вызов функции над ним. Оценка верхнего элемента стека вызвала ошибку (или во время его вычисления вычисление было прервано). Показанный стек является виртуальным, поскольку он не соответствует фактическому стеку времени выполнения. Фактический стек времени выполнения позволяет выполнять отложенную оценку, тогда как виртуальный стек соответствует стеку, который будет использоваться для тщательной (строгой) оценки.

Используя ту же программу-пример, что и выше, hat-stack показывает

$ hat-stack Example
Program terminated with error:
        No match in pattern.
Virtual stack trace:
(Last.hs:6)     last' []
(Last.hs:6)     last' [_]
(Last.hs:6)     last' [_,_]
(Last.hs:4)     last' [8,_,_]
(unknown)       main
$

В наши дни GHCi (& ge; 6.8.1) также поставляется с отладчиком:

$ ghci -fbreak-on-exception
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l Example.hs
[1 of 1] Compiling Main             ( Example.hs, interpreted )

Example.hs:5:0:
    Warning: Pattern match(es) are overlapped
             In the definition of `last'': last' [x] = ...
Ok, modules loaded: Main.
*Main> :trace main
(8,Stopped at <exception thrown>
_exception :: e = _
[<exception thrown>] *Main> :back
Logged breakpoint at Example.hs:(5,0)-(6,12)
_result :: t
[-1: Example.hs:(5,0)-(6,12)] *Main> :hist
-1  : last' (Example.hs:(5,0)-(6,12))
-2  : last' (Example.hs:5:15-22)
-3  : last' (Example.hs:(5,0)-(6,12))
-4  : last' (Example.hs:5:15-22)
-5  : last' (Example.hs:(5,0)-(6,12))
-6  : last' (Example.hs:5:15-22)
-7  : last' (Example.hs:(5,0)-(6,12))
-8  : main (Example.hs:3:25-32)
-9  : main (Example.hs:2:17-19)
-10 : main (Example.hs:2:16-34)
-11 : main (Example.hs:3:17-23)
-12 : main (Example.hs:3:10-33)
<end of history>
[-1: Example.hs:(5,0)-(6,12)] *Main> :force _result
*** Exception: Example.hs:(5,0)-(6,12): Non-exhaustive patterns in function last'

[-1: Example.hs:(5,0)-(6,12)] *Main> :back
Logged breakpoint at Example.hs:5:15-22
_result :: t
xs :: [t]
[-2: Example.hs:5:15-22] *Main> :force xs
xs = []

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

0 голосов
/ 30 апреля 2009

Частичным решением является использование вакуума для визуализации структур данных.

Я видел несколько gif-анимаций сгиба, сканирования и других, но пока не могу их найти. Я думаю, что Кейл Гиббард сделал анимацию.

0 голосов
/ 29 апреля 2009

Ничего подобного не встроено в стандарт Haskell.

Я бы надеялся, что графический интерпретатор Helium предложит что-то подобное, но веб-страница об этом молчит.

0 голосов
/ 29 апреля 2009

Существует сокращение количества объятий, если это помогает? В качестве альтернативы, вы могли бы использовать что-то вроде капюшона объятий, чтобы обернуть ваш код, чтобы получить более подробную информацию о том, что он делает на каждом этапе?

...