2017-12-16 6:33 GMT+01:00 David Feuer <david.feuer@gmail.com>:
The documentation for pokeByteOff indicates that the following equality holds:

  pokeElemOff addr idx x =
    poke (addr `plusPtr` (idx * sizeOf x)) x

[...] Was this intentional?

Yep, that was intentional, think of pokeElemOff as indexing into an array. Note that the FFI intentionally does not specify how to (un)marshal structs, only basic types and arrays of them. Doing anything else would be a) language-specific and b) platform-ABI-specific. Storable is just meant as a basic building block to do such more involved things.
 
If so, I believe sizeOf and alignment should document the law. [...]

Perhaps, but what exactly do you feel is missing there?