gpt4 book ai didi

haskell - 为什么在使用 withFrozenCallStack 时 HasCallStack 仍会添加堆栈帧?

转载 作者:行者123 更新时间:2023-12-03 14:58:52 26 4
gpt4 key购买 nike

GHC 8 提供 HasCallStack来自 GHC.Stack模块,它允许函数在调用时请求记录堆栈帧。它还提供withFrozenCallStack函数,它“卡住”调用堆栈,因此不能再向其中添加帧。

在简单的情况下,这可以按我的预期工作。例如:

ghci> let foo :: HasCallStack => CallStack
foo = callStack
ghci> foo
[("foo",SrcLoc {srcLocPackage = "interactive", srcLocModule = "Ghci2", srcLocFile = "<interactive>", srcLocStartLine = 8, srcLocStartCol = 1, srcLocEndLine = 8, srcLocEndCol = 4})]
ghci> withFrozenCallStack foo
[]

当我调用 foo通常,我得到一个堆栈帧,但是当我用 withFrozenCallStack 包装它时, 我不。完美的。然而,当这个例子稍微复杂一点时,它就不再像我预期的那样表现了:
ghci> let foo :: CallStack
foo = bar
bar :: HasCallStack => CallStack
bar = callStack
ghci> foo
[("bar",SrcLoc {srcLocPackage = "interactive", srcLocModule = "Ghci9", srcLocFile = "<interactive>", srcLocStartLine = 24, srcLocStartCol = 11, srcLocEndLine = 24, srcLocEndCol = 14})]
ghci> withFrozenCallStack foo
[("bar",SrcLoc {srcLocPackage = "interactive", srcLocModule = "Ghci9", srcLocFile = "<interactive>", srcLocStartLine = 24, srcLocStartCol = 11, srcLocEndLine = 24, srcLocEndCol = 14})]

通过添加这个简单的间接层,尽管我使用了 withFrozenCallStack,堆栈帧仍然被包含在内。 .为什么?

从概念上讲,我对 HasCallStack 的理解是不是就像隐式使用 pushCallStack在当前调用堆栈上,和 pushCallStack对卡住的调用堆栈没有影响。那么,为什么 withFrozenCallStack不阻止上面的堆栈帧被添加到调用堆栈?

最佳答案

在您的代码中,fooCallStack 类型的静态值.请注意,它没有 HasCallStack约束。

使用方式和地点无关紧要foo ,它将始终引用这个特定的 CallStack .没关系foo本身是使用 bar 定义的它使用 HasCallStack机器——你可以静态定义foo = [("bar",… .

尝试添加 HasCallStack =>foo的类型签名。它现在的行为是否符合您的预期?

关于haskell - 为什么在使用 withFrozenCallStack 时 HasCallStack 仍会添加堆栈帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40855484/

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