有没有办法在Haskell中查看缩减步骤,即跟踪递归函数调用?例如,Chez Scheme为我们提供了trace-lambda。 Haskell中是否有类似的形式?
有没有办法在Haskell中查看缩减步骤,即跟踪递归函数调用?例如,Chez Scheme为我们提供了trace-lambda。 Haskell中是否有类似的形式?
Debug.Trace.trace
,但这会有以下倾向:(a)产生非常混乱的输出,因为您的跟踪语句可能属于一个thunk,直到远离原始调用才被评估; (b)如果跟踪需要评估本来不会被评估的内容,则会更改程序的运行时行为。
这是用于调试吗? 如果是...
Hat修改您的源代码以输出跟踪信息,可以在运行后查看。 输出应该与您想要的相当接近:他们主页上的示例是
近年来,GHCi(≥6.8.1)也配备了调试器:For example, the computation of the faulty program
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
gives the result
(8, No match in pattern.
and the Hat viewing tools can be used to explore its behaviour as follows:
- Hat-stack
For aborted computations, that is computations that terminated with an error message or were interrupted, hat-stack shows in which function call the computation was aborted. It does so by showing a virtual stack of function calls (redexes). Thus, every function call shown on the stack caused the function call above it. The evaluation of the top stack element caused the error (or during its evaluation the computation was interrupted). The stack shown is virtual, because it does not correspond to the actual runtime stack. The actual runtime stack enables lazy evaluation whereas the virtual stack corresponds to a stack that would be used for eager (strict) evaluation.
Using the same example program as above, hat-stack shows
$ 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 -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 = []
在拥抱中有一个减少计数,这有帮助吗? 或者,您可以使用拥抱外壳来包装您的代码,以便在每个步骤中获得更多详细信息。