简体   繁体   English

查看Haskell中的减少步骤

[英]View Reduction Steps in Haskell

Is there any way to view the reduction steps in haskell, ie trace the recursive function calls made? 有没有办法查看haskell中的还原步骤,即跟踪所做的递归函数调用? For example, chez scheme provides us with trace-lambda. 例如,chez方案为我们提供了trace-lambda。 Is there an equivalent form in Haskell? Haskell中有一个等价的形式吗?

You could try inserting Debug.Trace.trace in places you want to trace, but this has the tendency of (a) producing wildly out-of-order output, as your trace statement may belong to a thunk that isn't evaluated until far far away from the original call, and (b) changing the runtime behavior of your program, if tracing requires evaluating things that wouldn't otherwise have been evaluated (yet). 您可以尝试在要跟踪的位置插入Debug.Trace.trace ,但这会导致(a)产生非常无序的输出,因为您的trace语句可能属于直到远未评估的thunk远离原始调用,以及(b)更改程序的运行时行为,如果跟踪需要评估本来不会被评估的事情(尚未)。

Is this for debugging? 这是用于调试吗? If so... 如果是这样的话...


Hat modifies your source code to output tracing which can be viewed after running. Hat会修改您的源代码以输出可在运行后查看的跟踪。 The output should be pretty close to what you want: the example on their homepage is 输出应该非常接近你想要的:他们主页上的例子是

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查看工具来探索其行为,如下所示:

  • 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). 它通过显示函数调用的虚拟堆栈(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 $ 

These days, GHCi (≥6.8.1) also comes with a debugger: 目前,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 = []

While not as nice, it has the benefit of being easily available, and being usable without recompiling your code. 虽然不那么好,但它具有易于使用的优点,并且无需重新编译代码即可使用。

There's a reduction count in hugs, if that helps? 如果有帮助的话,拥抱减少了吗? Alternatively, could you use something like the hugs hood to wrap your code, to get more detail around what it's doing at each step? 或者,您是否可以使用类似拥抱罩的东西来包装您的代码,以获得有关它在每一步中所做的更多细节?

Nothing of the kind is built into the Haskell standard. Haskell标准中没有构建任何类型的东西。

I would hope that the Helium graphical interpreter would offer something like this, but the web page is silent on the topic. 我希望Helium图形解释器可以提供类似这样的东西,但网页对这个主题保持沉默。

A partial solution is to use vacuum to visualize data structures. 部分解决方案是使用真空来可视化数据结构。

I've seen some gif animations of fold, scan and others, but I can't find them at the moment. 我已经看过折叠,扫描和其他的一些gif动画,但我现在找不到它们。 I think Cale Gibbard made the animations. 我认为Cale Gibbard制作了动画片。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM