gpt4 book ai didi

haskell - 严格声明的意义何在?

转载 作者:行者123 更新时间:2023-12-02 05:34:15 25 4
gpt4 key购买 nike

我正在启动 Haskell,并正在查看一些数据类型用“!”定义的库。来自字节串库的示例:

data ByteString = PS {-# UNPACK #-} !(ForeignPtr Word8) -- payload
{-# UNPACK #-} !Int -- offset
{-# UNPACK #-} !Int -- length

现在我看到了this question作为对这意味着什么的解释,我想这很容易理解。但我现在的问题是:使用这个有什么意义?既然表达式会在需要时被求值,为什么要强制早期求值呢?

在这个问题的第二个答案中,C.V.汉森说:“[...]有时懒惰的开销可能会太多或浪费”。这是否意味着它用于节省内存(保存值比保存表达式更便宜)?

如果有解释和例子就太好了!

谢谢!

[编辑]我认为我应该选择一个不带 {-# UNPACK #-} 的示例。那么就让我自己做一个吧。这有道理吗?是的,为什么以及在什么情况下?

data MyType = Const1 !Int
| Const2 !Double
| Const3 !SomeOtherDataTypeMaybeMoreComplex

最佳答案

这里的目标不是严格性,而是将这些元素打包到数据结构中。如果不严格限制,这三个构造函数参数中的任何一个都可以指向堆分配的值结构或堆分配的延迟求值 thunk。严格来说,它只能指向堆分配的值结构。通过严格和打包结构,可以使这些值内联。

由于这三个值中的每一个都是指针大小的实体,并且无论如何都严格访问,因此在使用此结构时强制使用严格且打包的结构可以节省指针间接寻址。

在更一般的情况下,严格注释可以帮助减少空间泄漏。考虑这样的情况:

data Foo = Foo Int

makeFoo :: ReallyBigDataStructure -> Foo
makeFoo x = Foo (computeSomething x)

如果没有严格注释,如果你只调用 makeFoo,它会构建一个 Foo 指向一个指向 ReallyBigDataStructure 的 thunk,同时保持它在内存中,直到有什么东西迫使 thunk 进行评估。如果我们有

data Foo = Foo !Int

这会强制 computeSomething 计算立即进行(好吧,一旦有东西强制 makeFoo 本身),这会避免留下对 ReallyBigDataStructure 的引用。

请注意,这是与字节串代码不同的用例;字节串代码非常频繁地强制其参数,因此不太可能导致空间泄漏。最好将字节串代码解释为纯粹的优化,以避免指针取消引用。

关于haskell - 严格声明的意义何在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6231821/

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