为什么用 UNPACK 和 strictness 标记记录字段很常见?

Why is it common to mark record fields with UNPACK and strictness?

我注意到这种模式在 Haskell 库中很常见:

data Foo = Foo { field :: {-# UNPACK #-} !Sometype } 

例如UNPACK设置字段类型并使其严格。

我明白 pragma 和注释的作用是什么,但我不明白为什么它如此普遍:我已经在 Haskell 编程 15 年了,很少使用严格注释,也从不 UNPACK 编译指示。

如果这个成语这么有用,为什么不减少它"ugly"?

pragma 可能有点难看,但它避免了很多 more 其他地方的丑陋。当性能至关重要时,程序员通常需要为数据构造函数选择特定的形状。假设我有

data Point = Point Int Int
data Segment = Segment Point Point

这在逻辑上很有道理,但它有一堆额外的间接:一个 Segment7 个 堆对象组成。如果我要处理很多细分市场,那就太糟糕了。

我可以用手压扁这个公寓:

data Segment = Segment Int# Int# Int# Int#

但现在我忘记了数字代表点的事实,我对段所做的一切都将不得不涉及相当不方便和奇怪的拆箱操作。

幸运的是,有更好的方法:

-- The small strict Int fields will be unpacked by default
-- with any reasonably recent GHC version.
data Point = Point !Int !Int

data Segment = Segment {-# UNPACK #-} !Point {-# UNPACK #-} !Point

这仍然为每个段提供一个堆对象,但我可以使用 Points 和 Ints 并且(通常)依赖编译器很好地拆箱所有内容。