Ответ 1
Вы можете попробовать вставить Debug.Trace.trace
в местах, которые вы хотите проследить, но это имеет тенденцию: (a) производить дико из-за вывода, поскольку ваш оператор трассировки может принадлежать thunk, который не оценивается до далекого далекого от первоначального вызова, и (b) изменения поведения во время выполнения вашей программы, если трассировка требует оценки вещей, которые иначе не имели бы (пока).
Это для отладки? Если так...
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-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 (& 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 = []
Несмотря на то, что он не так хорош, он имеет преимущество в том, что он легко доступен и может использоваться без перекомпиляции кода.