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

ins*_*itu 8 haskell ghc

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

data Foo = Foo { field :: {-# UNPACK #-} !Sometype } 
Run Code Online (Sandbox Code Playgroud)

例如,UNPACK一个字段的类型并使其严格.

我理解pragma和注释的效果是什么,但我不明白为什么它如此普遍:我已经在Haskell编程了15年并且很少使用严格注释,而且从不使用UNPACKpragma.

如果这个成语如此有用,为什么不让它变得不那么"难看"呢?

dfe*_*uer 7

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

data Point = Point Int Int
data Segment = Segment Point Point
Run Code Online (Sandbox Code Playgroud)

这具有良好的逻辑意义,但它有一堆额外的间接:一个Segment七个堆对象组成.如果我正在处理很多细分,那就非常糟糕.

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

data Segment = Segment Int# Int# Int# Int#
Run Code Online (Sandbox Code Playgroud)

但是现在我已经失去了这样一个事实:数字代表了点数,而我对一个片段所做的一切都将涉及相当不方便和奇怪的无箱操作.

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

-- 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
Run Code Online (Sandbox Code Playgroud)

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