Look at the definition of SerializedCompact (in ghc-compact):
data SerializedCompact a = SerializedCompact
{ serializedCompactBlockList :: [(Ptr a, Word)]
, serializedCompactRoot :: Ptr a
}
The type variables on those Ptrs are a lie. The SerializedCompact needs that phantom type variable to keep track of what type of object in a compact region is represented by these blocks. But, the types of its two fields are extremely misleading. When I first saw this type, I was led to believe that I could call `peek` on the `serializedCompactRoot` field and get a value of type `a`. You cannot actually do that since it isn't actually a pointer to a value of that type. More correct would be:
data SerializedCompact a = SerializedCompact
{ serializedCompactBlockList :: [(Addr, Word)]
, serializedCompactRoot :: Addr
}
This better documents what's actually going on here. We don't have a bunch of pointers to `a` values in a list. We value memory addresses that refer to arbitrary fragments of an object on the heap.