[Haskell-cafe] What can be UNPACK'ed?

Nick Smallbone nick at smallbone.se
Mon Jul 31 21:44:20 UTC 2017

Tom Ellis <tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk> writes:

> Thanks, that's helpful info, but what I'm really after is a definitive
> condition under which fields can be UNPACK'ed.  The docs are very vague:
>     https://downloads.haskell.org/~ghc/7.0.2/docs/html/users_guide/pragmas.html

As far as I know, the restrictions for UNPACKing a field are as follows:
   * The field's type must have only one constructor
   * The type must not be just a type variable
     (i.e., the constructor must be known at compile time)
   * The field must be strict
     (this is because otherwise, UNPACKing changes the semantics of the
     data type you are declaring by making it more strict)

So, for example, lists cannot be UNPACKed (because they have two
constructors, nil and cons). Nor can polymorphic fields (because there
may or may not be only one constructor).

To apply this to primitive types, you have to know how they are defined.
For example, Int can be UNPACKed because it has only one constructor:

  data Int = I# Int#

But Integer cannot be UNPACKed because it has several constructors:

  data Integer  = S#                !Int#
                | Jp# {-# UNPACK #-} !BigNat
                | Jn# {-# UNPACK #-} !BigNat

In practice, most primitive types apart from Integer can be UNPACKed -
but to be sure you have to look at the standard library source code
(or just pay attention to the compiler warnings).


More information about the Haskell-Cafe mailing list