Haskell中的无限递归

5
这个问题本质上是使用GHCi调试Haskell程序中的无限循环的重复问题。作者手动解决了这个问题,但我想知道其他的解决方案。

(我的具体问题)

我有一个包含递归调用的箭头代码。

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 路线并绕过递归调用。
很奇怪的是,在常见的地方插入 "trace" 调用(比如函数组合),程序会发出有限数量的输出,然后冻结。这不是我从无限项扩展问题中期望得到的结果。(请参见编辑1)
如果有人感兴趣,我已经上传了我的源代码在这里

编辑 1

我没有看对地方(如果你想查看源代码,请注意,显然 avEither 在循环)。我找到它的方法是通过编译二进制文件,然后运行 gdb
  • gdb Main
  • r (运行代码)
  • Ctrl+C (发送中断信号)。回溯将毫无用处,但您可以做的是按下
  • s (步进)。然后,按住回车键;您应该会看到很多方法名飞过。希望其中一个是可识别的。
您可以使用 ghc 标志 -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>

修改后的源代码在这里


在重复的问题链接中,作者手动解决了它,其他用户在评论中询问了源代码。因此,我开始了这个问题。我肯定会进行调试,并在发现更多信息时更新此页面。如果有人知道自动技术,请告诉我,我是Haskell新手,非常感谢。 - gatoatigrado
哦,我以为gdb不能与基于http://hackage.haskell.org/trac/ghc/wiki/Debugging/CompiledCode?redirectedfrom=DebuggingGhcCrashes的ghc一起使用。 - Adam
你看不到真正的堆栈跟踪,但是可以看到一些方法名称。对于此示例,请下载原始的AVFunctor.zip(在编辑部分之前的链接),然后运行 ghc -O0 --make Main.hs,然后运行 gdb Main,并执行 rctrl+cs,如上所述。您将看到类似于此处的内容,http://pastebin.com/xSJ9uMn3 。 - gatoatigrado
1个回答

3

请注意,(|||)的含义取决于箭头,而testAVFunctor是您的箭头的无限对象:

testAVFunctor = proc x -> do
    ...
    (passError ||| proc x -> do
                       ...
                       (passError ||| proc x -> ...) -< trace "value of z" z)
        -< trace "value of z" z

我不确定你是否意识到了这一点。请检查(|||)的定义(如果没有定义,则检查left),以查看它是否能够处理无限期限。还要检查(>>>)(哦,我想现代版本中是(.))。确保组合器不是严格的,因为那样一个无限期限将会发散。这可能涉及使用~使模式更懒惰(当我使用箭头时,我经常不得不这样做)。您看到的行为可能是由于其中一个组合器过于严格而导致的,因此它评估“足够远”以提供一些输出,但随后卡住了。

祝你好运。你已经进入了Haskell的深层微妙之中。


谢谢,我需要它:)。我正在检查(|||)的过程中;很可能就在那里。在一个更简单的例子中,我用<code>~</code>有了一些运气,谢谢! - gatoatigrado

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接