为什么 GHC Haskell 中的无效构造函数需要两个机器字?

问题描述 投票:0回答:1

我在 GHC 中尝试了

closureSize#
原语。在这里,我定义了我使用的辅助函数(
x
强制使用爆炸模式,所以我测量的应该是数据构造函数闭包本身而不是重击)。

{-# LANGUAGE MagicHash #-}
import GHC.Exts
import Text.Printf
size :: Show a => a -> IO ()
size !x = printf "sizeof %s = %d\n" (showsPrec 11 x "") (I# (closureSize# x))

现在在 GHCi 中,以下是奇怪的结果:

GHCi> size ()
sizeof () = 2
GHCi> size (MkSolo 1)
sizeof (MkSolo 1) = 2
GHCi> size (1, 2)
sizeof (1,2) = 3
GHCi> size (1, 2, 3)
sizeof (1,2,3) = 4
GHCi> size Nothing
sizeof Nothing = 2
GHCi> size (Just 42)
sizeof (Just 42) = 2
GHCi> size []
sizeof [] = 2
GHCi> size [1, 2, 3]
sizeof [1,2,3] = 3

除了无效构造函数之外的所有内容对我来说都有意义。我认为他们应该只为 STG 信息标题采用一个单词,但实际上他们采用了两个单词。这是由于 GHC RTS 中的某些限制导致每个闭包必须至少有一个有效负载字吗?

haskell ghc
1个回答
0
投票

令人惊讶的是,无效构造函数使用与一元构造函数相同的表示形式。您可以使用 GHC 的

ghc-heap
库来确认这一点。

$ ghci
> :set -package ghc-heap
package flags have changed, resetting and loading new packages...
> import GHC.Exts.Heap
> getClosureData Nothing
ConstrClosure {info = StgInfoTable {entry = Nothing, ptrs = 0, nptrs = 1, tipe = CONSTR_0_1, srtlen = 0, code = Nothing}, ptrArgs = [], dataArgs = [140686603053880], pkg = "base", modl = "GHC.Maybe", name = "Nothing"}

闭包类型(

tipe
字段)是
CONSTR_0_1
:具有
CONSTR
指针字段和
0
非指针字段的
1
向量。请注意,没有
CONSTR_0_0
闭合类型(请参阅
ClosureType
)。我不知道为什么会这样。我鼓励您在 Haskell 邮件列表或 Discourse 上提出这个问题,以获得更专业的答案!

这个关于堆对象的旧 GHC wiki 页面解释了这些闭包类型对应的内容。

© www.soinside.com 2019 - 2024. All rights reserved.