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

Nick Smallbone nick at smallbone.se
Wed Aug 2 17:27:04 UTC 2017


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

> On Mon, Jul 31, 2017 at 11:44:20PM +0200, Nick Smallbone wrote:
>>    * The type must not be just a type variable
>>      (i.e., the constructor must be known at compile time)
>
> Eventually I'd like to see if we can relax this condition but first ...

(Take everything I say here with a pinch of salt: I'm not a GHC developer.)

IIUC, relaxing this would be difficult because GHC compiles using type
erasure. For example, if I have a type

   data Whatever a = Whatever !a

then values of type Whatever Int and Whatever Float are represented in
exactly the same way at runtime. However, if we were to unpack the 'a',
then they would internally have to be turned into two different types:
   data WhateverInt = Whatever Int#
   data WhateverFloat = Whatever Float#
This would in turn mean that a polymorphic function
   f :: Whatever a -> ...
would have to be compiled into two separate versions, one for Whatever
Int and one for Whatever Float, which is something that GHC doesn't do.

>>    * The field's type must have only one constructor
>
> Do you know the rationale for this?  It seems like there should be no
> problem unpacking a constructor tag plus payload, even if the payload size
> varies, as long as the maximum payload size in known.

One thing is that UNPACK right now can be implemented just by a simple
program transformation. When you declare a datatype with an unpacked
field, such as
  data T a b = C {-# UNPACK #-} !Int {-# UNPACK #-} !(a, b),
then GHC secretly replaces the datatype with the unpacked version, in
this case:
  data T a b = UnpackedC Int# a b
Then all uses of the constructor C are rewritten to use UnpackedC instead.
The resulting program is still type-correct - in fact, it is still a
normal Haskell (well, GHC core) program. This transformation happens
quite early on during compilation and AIUI the rest of the compiler
doesn't have to know about unpacking at all.

If you try to unpack a field that has multiple constructors this way,
it's not clear what the unpacked datatype should look like - I suppose
it'd need to be some kind of union. So at least it's not immediately
obvious how to do this...

Nick



More information about the Haskell-Cafe mailing list