gpt4 book ai didi

debugging - Haskell 中的无限递归

转载 作者:行者123 更新时间:2023-12-03 07:58:55 24 4
gpt4 key购买 nike

这个问题本质上是 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 标志进行编译 -O0禁用优化,这可以显示更多方法名称。

    编辑 3

    显然, proc x -> do上面的块导致代码生成组合子,这些组合子调用了 AVFunctor.arr提升法被称为——里面的东西一定是违反了懒惰的。如果我将顶级函数重写为
    testAVFunctor = errorArrow "good error" >>>
    isError >>> (passError ||| testAVFunctor)

    然后一切正常。我想是时候尝试学习和使用 garrows (由伯克利的一名研究生提供)。

    我从经验中得出的一般结论是 ghci 调试可能令人沮丧。例如,我设法提出了 f 的论点。的 AVFunctor.arr显示为局部变量,但我无法从中获得任何非常有用的信息:
    > :i f
    f :: b -> c -- <no location info>

    修改后的源代码是 here

    最佳答案

    请记住(|||)的含义取决于箭头,和 testAVFunctor是你的箭头的无限对象:

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

    我不确定你是否知道这一点。检查 (|||) 的定义(或者如果没有, left )看看它是否可以处理无限项。另请检查 (>>>) (呃, (.) 在我认为的现代版本中)。确保组合子不是严格的,因为这样无限项就会发散。这可能涉及使用 ~ 使模式变得更懒惰(在使用箭头时,我不得不经常这样做)。您所看到的行为可能是由于其中一个组合器过于严格造成的,因此它评估“足够远”以提供一些输出,但稍后会卡住。

    祝你好运。您深入了解 Haskell 的微妙之处。

    关于debugging - Haskell 中的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5846660/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com