Просмотр шагов сокращения в Haskell
есть ли способ просмотреть шаги сокращения в haskell, i.e отслеживать вызовы рекурсивных функций? Например, схема chez предоставляет нам trace-lambda. Есть ли эквивалентная форма в Haskell?
4 ответов
вы можете попробовать вставить Debug.Trace.trace
в местах, которые вы хотите проследить, но это имеет тенденцию (a) производить дико неупорядоченный вывод, Поскольку ваш оператор трассировки может принадлежать thunk, который не оценивается до тех пор, пока далеко от исходного вызова, и (b) изменение поведения среды выполнения вашей программы, если трассировка требует оценки вещей, которые в противном случае не были бы оценены (пока).
это для отладки? Если так...
шляпа изменяет исходный код для вывода трассировки, которую можно просмотреть после запуска. Вывод должен быть довольно близок к тому, что вы хотите: пример на их домашней странице -
например, вычисление неисправной программы
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-stack показывает, в какой функции вызов вычисления был прерван. Он делает это, показывая виртуальный стек вызовов функций (redexes). Таким образом, каждый вызов функции, показанный в стеке, вызывал вызов функции над ним. Оценка верхнего элемента стека вызвала ошибку (или во время ее оценки вычисление был прерван). Показанный стек является виртуальным, поскольку он не соответствует фактическому стеку времени выполнения. Фактический стек времени выполнения включает ленивую оценку, тогда как виртуальный стек соответствует стеку, который будет использоваться для нетерпеливой (строгой) оценки.
используя тот же пример программы, что и выше, 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 (≥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 = []
пока не как славный, оно имеет преимущество быть легко доступным и пригодным для использования без перекомпиляции кода.
есть сокращение количества объятий, если это поможет? В качестве альтернативы, вы можете использовать что-то вроде hugs hood, чтобы обернуть свой код, чтобы получить более подробную информацию о том, что он делает на каждом шаге?
ничего подобного не встроено в стандарт Haskell.
Я надеюсь, что гелий графический интерпретатор предложил бы что-то вроде этого, но веб-страница молчит по этой теме.
частичное решение-использовать вакууме для визуализации структур данных.
Я видел некоторые GIF-анимации сгиба, сканирования и других, но я не могу найти их на данный момент. Думаю, анимацию сделал Кейл Гиббард.