Primitive arrays, mutable and otherwise

GHC knows about quite a few flavours of Large Swathes of Bytes.

First, GHC distinguishes between primitive arrays of (boxed) Haskell objects (type Array# obj) and primitive arrays of bytes (type ByteArray#).

Second, it distinguishes between…

Immutable:

Arrays that do not change (as with “standard” Haskell arrays); you can only read from them. Obviously, they do not need the care and attention of the state-transformer monad.

Mutable:

Arrays that may be changed or “mutated.” All the operations on them live within the state-transformer monad and the updates happen in-place.

“Static” (in C land):

A C routine may pass an Addr# pointer back into Haskell land. There are then primitive operations with which you may merrily grab values over in C land, by indexing off the “static” pointer.

“Stable” pointers:

If, for some reason, you wish to hand a Haskell pointer (i.e., not an unboxed value) to a C routine, you first make the pointer “stable,” so that the garbage collector won't forget that it exists. That is, GHC provides a safe way to pass Haskell pointers to C.

Please see the section called Subverting automatic unboxing with “stable pointers” for more details.

“Foreign objects”:

A “foreign object” is a safe way to pass an external object (a C-allocated pointer, say) to Haskell and have Haskell do the Right Thing when it no longer references the object. So, for example, C could pass a large bitmap over to Haskell and say “please free this memory when you're done with it.”

Please see the section called Foreign objects: pointing outside the Haskell heap for more details.

The libraries documentatation gives more details on all these “primitive array” types and the operations on them.