Вы можете попробовать вставить 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-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 = []
Хотя это и не так хорошо, оно имеет преимущество в том, что оно легко доступно и может использоваться без перекомпиляции кода.