Search code examples
haskellindirection

What does the UNPACK pragma do, in this case?


I have trouble understanding how UNPACK works in Haskell. Consider, for example, the following data declarations:

data P a b = P !a !b
data T = T {-# UNPACK #-} !(P Int Int)

How will datatype T be unpacked? Will it be equivalent to

data T' = T' !Int !Int

or will the Ints be further unpacked:

data T'' = T'' Int# Int#

? What about

data U = U {-# UNPACK #-} !(P Int (P Int Int))

?


Solution

  • The GHC documentation describes the UNPACK pragma as follows:

    The UNPACK indicates to the compiler that it should unpack the contents of a constructor field into the constructor itself, removing a level of indirection.


    How will datatype T be unpacked?

    data T = T (P Int Int) corresponds to

    non-unpacked data

    Therefore, data T = T {-# UNPACK #-} !(P Int Int) corresponds to

    pair unpacked

    In plain English, UNPACK has unpacked the contents of constructor P into the field of constructor T, removing one level of indirection and one constructor header (P).

    data T = T {-# UNPACK #-} !(P Int Int) isn't as "compact" as data T'' = T'' Int# Int#:

    completely unpacked


    What about

    data U = U {-# UNPACK #-} !(P Int (P Int Int))
    

    ?

    Similarly, data U = U (P Int (P Int Int)) corresponds to

    pair of pairs

    and data U = U {-# UNPACK #-} !(P Int (P Int Int)) corresponds to

    unpacked pair of pairs

    In plain English, UNPACK has unpacked the contents of constructor P into the field of constructor U, removing one level of indirection and one constructor header (P).

    Resources