Debugging 查看Haskell中的简化步骤

Debugging 查看Haskell中的简化步骤,debugging,haskell,functional-programming,reduction,Debugging,Haskell,Functional Programming,Reduction,有没有办法查看haskell中的缩减步骤,即跟踪递归函数调用?例如,chez方案为我们提供了跟踪lambda。Haskell中是否有一个等价的形式?如果有帮助的话,拥抱的数量会减少吗? 或者,您是否可以使用类似hugs hood的东西来包装代码,以获得关于它在每个步骤中所做工作的更多细节?Haskell标准中没有内置此类内容 我希望图形解释器会提供类似的内容,但网页对此主题没有任何提示。您可以尝试在要跟踪的位置插入,但这有(a)产生无序输出的趋势,由于跟踪语句可能属于一个thunk,它在远离原始

有没有办法查看haskell中的缩减步骤,即跟踪递归函数调用?例如,chez方案为我们提供了跟踪lambda。Haskell中是否有一个等价的形式?

如果有帮助的话,拥抱的数量会减少吗?
或者,您是否可以使用类似hugs hood的东西来包装代码,以获得关于它在每个步骤中所做工作的更多细节?

Haskell标准中没有内置此类内容

我希望图形解释器会提供类似的内容,但网页对此主题没有任何提示。

您可以尝试在要跟踪的位置插入,但这有(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堆栈显示中止计算的函数调用。它通过显示函数调用的虚拟堆栈(重新定义)来实现。因此,堆栈上显示的每个函数调用都会导致它上面的函数调用。对顶层堆栈元素的求值导致错误(或在求值过程中计算中断)。显示的堆栈是虚拟的,因为它与实际的运行时堆栈不对应。实际运行时堆栈支持延迟计算,而虚拟堆栈对应于用于急切(严格)计算的堆栈

使用与上面相同的示例程序,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 = []
$ghci-异常时fbreak
GHCi,6.10.1版:http://www.haskell.org/ghc/  :? 求救
正在加载程序包ghc prim。。。链接。。。完成。
正在加载包整数。。。链接。。。完成。
正在加载包库。。。链接。。。完成。
前奏曲>:l Example.hs
[1/1]编译Main(Example.hs,已解释)
示例.hs:5:0:
警告:模式匹配重叠
在“last”的定义中:last'[x]=。。。
好的,模块已加载:Main。
*Main>:跟踪Main
(8)在
_异常::e=_
[]*Main>:返回
记录的断点位于Example.hs:(5,0)-(6,12)
_结果::t
[-1:Example.hs:(5,0)-(6,12)]*Main>:hist
-1:last'(例如:hs:(5,0)-(6,12))
-2:last'(示例hs:5:15-22)
-3:last'(例如:hs:(5,0)-(6,12))
-4:last'(示例hs:5:15-22)
-5:last'(例如:hs:(5,0)-(6,12))
-6:last'(示例hs:5:15-22)
-7:last'(例如:hs:(5,0)-(6,12))
-8:main(示例hs:3:25-32)
-9:main(示例hs:2:17-19)
-10:main(示例hs:2:16-34)
-11:main(示例hs:3:17-23)
-12:main(示例hs:3:10-33)
[-1:Example.hs:(5,0)-(6,12)]*Main>:力结果
***例外:Example.hs:(5,0)-(6,12):函数last'中的非穷举模式
[-1:Example.hs:(5,0)-(6,12)]*Main>:返回
示例中记录的断点。hs:5:15-22
_结果::t
xs::[t]
[-2:Example.hs:5:15-22]*Main>:forcexs
xs=[]

虽然不是很好,但它的优点是易于使用,并且无需重新编译代码即可使用。

部分解决方案是使用可视化数据结构


我看过一些折叠、扫描和其他的gif动画,但我现在找不到。我认为是Cale Gibbard制作的动画。

Scheme与Scheme有很大的不同;Haskell很懒,所以实际评估可能会在通话后很久进行。