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中使用?