gpt4 book ai didi

haskell - GHC StablePointer 等式推理

转载 作者:行者123 更新时间:2023-12-04 11:36:50 24 4
gpt4 key购买 nike

我刚刚了解了GHC的StablePointer功能,这真的很酷,但我不明白为什么它不会显示平等。这是我的测试用例:

-- Example 1
import System.Mem.StableName

data Wrapper = Wrapper { getWrapper :: Int -> Bool }

myFunc :: Int -> Bool
myFunc = (> 4)

main :: IO ()
main = do
let m = Wrapper myFunc
a <- makeStableName $ getWrapper m
b <- makeStableName $ getWrapper m
print (a `eqStableName` b)
putStrLn "Done"

很简单,但是当我这样做时 runhaskell使用 GHC 7.8.4,我得到一个错误的结果。更简单的情况呢?让我们试试这个:
-- Example 2
import System.Mem.StableName

main :: IO ()
main = do
let m = (+2) :: Int -> Int
n = m
a <- makeStableName m
b <- makeStableName n
print (a `eqStableName` b)
putStrLn "Done"

我仍然得到 False 的结果。我能得到 eqStableName的唯一方法返回 True当我调用 makeStableName在相同的精确绑定(bind)变量上。像这样:
  -- in this example, r can be anything
a <- makeStableName r
b <- makeStableName r
print (a `eqStableName` b)

但这不再有用。我已经知道每个表达式都等于它自己,所以这并没有给我任何新信息。我的问题是双重的:
  • 什么用例是StablePointer打算满足?
  • 我们如何推断 StablePointer 的相等性? .我知道它会给出假阴性,但在什么情况下我可以期望这些总是发生?

  • 感谢您的任何见解。他们非常感激。

    - 编辑 -

    我发现如果我用 ghc 构建它而不是 runhaskell , 那么示例 2 实际上确实表明它们是相等的。示例 1 仍然失败。问题仍然存在。

    最佳答案

    那些返回的原因False大概是懒惰吧。在 GHC 中,mn将引用不同的 thunk,因为它们尚未评估。 makeStableName不强制该值。如果您手动强制 thunk,它们将是相同的:

      let m = Wrapper myFunc
    a <- makeStableName $! getWrapper m
    b <- makeStableName $! getWrapper m
    print (a `eqStableName` b)

    这将打印 True ( $! 将强制 getWrapper 返回的值到 WHNF)。

    请注意,如果您不使用 runhaskell而是用 -O1 编译, GHC 将实际编译此代码,使其打印 True .从Core看,似乎GHC所做的是内联 mgetWrapper因此运行的代码实际上是这样的:
    a <- makeStableName myFunc
    b <- makeStableName myFunc

    然后当然会生成相同的稳定指针。

    因此,如果您想要最大程度的平等,请始终在创建指向它们的稳定指针之前强制您的值。但是,如果两个值相等,则不能保证它们被分配相等的稳定指针。

    如果你还没看过,我也推荐阅读 Stretching the storage manager这解释了稳定指针的实现。

    关于haskell - GHC StablePointer 等式推理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29653453/

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