【发布时间】:2011-08-16 08:12:54
【问题描述】:
这个问题本质上是Debugging infinite loops in Haskell programs with GHCi 的重复。 那里的作者手动解决了,不过我想知道其他解决方案。
(我的特殊问题)
我有一个包含递归调用的箭头代码,
testAVFunctor = proc x -> do
y <- errorArrow "good error" -< x
z <- isError -< y
(passError ||| testAVFunctor) -< trace "value of z" z
errorArrow 应该使递归 testAVFunctor 不执行,因为这将导致 isError 返回一个 Left (AVError "good error"),这应该反过来选择 passError 路由并绕过递归调用。
非常奇怪的是,在函数组合等流行站点插入“跟踪”调用会导致程序发出有限数量的输出,然后冻结。不是我对无限项扩展问题的期望。(见编辑 1)
如果有人好奇,我已经上传了我的源代码here。
编辑 1
我没有找对地方(如果您想查看源代码,显然 avEither 正在循环)。我到达那里的方法是编译一个二进制文件,然后运行 gdb:
- gdb 主要
- r (运行代码)
- Ctrl+C (发送中断)。回溯将是无用的,但你能做的,就是命中
- s (步骤)。然后,按住回车键;您应该会看到很多方法名称飞过。希望其中一个能被认出来。
您可以使用 ghc flag -O0 进行编译以禁用优化,这可以显示更多方法名称。
编辑 3
显然,上面的 proc x -> do 块导致代码生成组合器,它们正在调用 AVFunctor.arr 提升方法被调用——其中的某些东西一定违反了惰性。如果我将顶层函数重写为
testAVFunctor = errorArrow "good error" >>>
isError >>> (passError ||| testAVFunctor)
然后一切正常。我想是时候尝试学习和使用garrows(由伯克利的一名研究生提供)。
我从经验中得出的一般结论是 ghci 调试可能会令人沮丧。例如,我设法使AVFunctor.arr 的参数f 显示为局部变量,但我无法从中获得任何非常有用的信息:
> :i f
f :: b -> c -- <no location info>
修改后的源代码为here
【问题讨论】:
-
在链接的重复问题上,作者手动解决了,其他评论那里的用户已经询问了出处。所以,我开始了这个问题。我当然正在调试它,并会在我发现更多信息时更新此页面。如果有人知道自动技术,我将不胜感激——我是一个 haskell 新手。
-
嗯,我认为 gdb 不能与基于 hackage.haskell.org/trac/ghc/wiki/Debugging/… 的 ghc 一起工作
-
您看不到真正的堆栈跟踪,但您可以看到一些方法名称。对于此示例,请下载原始 AVFunctor.zip(编辑部分之前的链接),然后运行
ghc -O0 --make Main.hs、gdb Main、r、ctrl+c和s,如上。你会看到类似这样的东西,pastebin.com/xSJ9uMn3。
标签: debugging haskell infinite-loop ghci arrows