i.e. the C info table, the field of type a, a length field, and the payload of the Array#.

For example we might use this to remove a layer of indirection in our immutable Array types.

Source API

For now instead of having an implicit unpacked Array# type, lets define a new type of unpacked arrays:

UnpackedArray#

(we can change the name later)

So the user would write:

data T a b = C a (UnpackedArray# b)
| ...

and we expose some new primitives:

indexUnpackedArray# :: UnpackedArray# a -> Int# -> (# a #)

The question is, how are we going to represent UnpackedArray#?

Suppose that the compiler desugars UnpackedArray# to a pair of values:

a pointer value (maybe type InteriorArrayContainer# a, but we could revisit this): this is a pointer to the containing constructor, C

an Int#, which is the offset of the beginning of the unpacked array relative to the info table of the C constructor, that is, the offset of the array's length field.

Now, any variable of type UnpackedArray# also gets desugared into a pair of variables with the above types. The indexUnpackedArray# primitive really takes *two* arguments, so let's give the desugared one a different name:

Note that the representation of the constructor C does not actually contain the two fields icarr# and off#, these are brought into existence (bound) by the code generator when generating the code for the C case alternative.

List of changes that we think are necessary

Add desugaring of unpacked array types in argument and field positions, and indexUnpackedArray# to indexInteriorArray# (somewhere under desugar/ probably)

Add code generation for case alternatives on constructors containing interior arrays, they have to bind variables to the InteriorArrayContainer# and offset (codeGen/CgCase.lhs, codeGen/StgCmmCase.lhs).