GHC在将总和类型传递给函数时是否解包过?例如,让我们说,我们有以下类型:总和类型函数参数的GHC调用约定
data Foo
= Foo1 {-# UNPACK #-} !Int {-# UNPACK #-} !Word
| Foo2 {-# UNPACK #-} !Int
| Foo3 {-# UNPACK #-} !Word
然后我定义一个函数,在其Foo
参数严格:
consumeFoo :: Foo -> Int
consumeFoo x = case x of ...
在运行时,当我打电话consumeFoo
,我能预计会发生? GHC calling convention是在寄存器中传递参数(或者在堆栈太多时在堆栈上)。我可以看到两种方法可以传递参数:
- 指向堆上的
Foo
的指针作为一个参数传入。 - 使用
Foo
的三个参数表示法,一个参数表示使用的数据构造函数,另外两个表示数据构造函数中可能的Int
和Word
值。
我宁愿第二个表示,但我不知道它是否实际上会发生什么。我知道UnpackedSumTypes登陆GHC 8.2,但目前还不清楚它是否符合我的要求。如果我已经写了这样的功能:
consumeFooAlt :: (# (# Int#, Word# #) | Int# | Word# #) -> Int
然后,我期望评估(2)将会发生什么。而拆包金额页的Unpacking section表明,我能做到这一点还有:
data Wrap = Wrap {-# UNPACK #-} !Foo
consumeFooAlt2 :: Wrap -> Int
而这也应该有我想要的表现,我想。
所以我的问题是,没有使用包装类型或原始解压缩的总和,我怎么能保证,当我把它作为参数传递给一个函数时,一个和解被解压到寄存器(或堆栈中)?如果可能的话,GHC 8.0已经可以做什么,或者它只能在GHC 8.2中使用?