
On Wed, 13 Dec 2017, David Feuer wrote:
+1, but we should also do this for sizeOf and alignment in Foreign.Storable.
If Storable would be intended for tuples, too, and there would be no padding, we could use special Monoids in Const, like so: class Storable a where sizeOf :: Const (Sum Int) a alignment :: Const (LCM Int) a instance (Storable a, Storable b) => Storable (a,b) where sizeOf = liftA2 (,) sizeOf sizeOf alignment = liftA2 (,) alignment alignment Taking alignment into account we could define data SizeAlign = SignAlign {sizeOf_, alignment_ :: Int} instance Monoid SizeAlign where mempty = SizeAlign 0 1 mappend x y = SizeAlign (sizeOf_ x + mod (- sizeOf_ x) (alignment_ y) + sizeOf_ y) (lcm (alignment_ x) (alignment_ y)) class Storable a where sizeAlign :: Const SizeAlign a instance (Storable a, Storable b) => Storable (a,b) where sizealign = liftA2 (,) sizeOf sizeOf However, SizeAlign.mappend this way is not valid because it violates associativity (e.g. sizes 1, 1, 2 with corresponding alignments). Even if it would be valid, it would still differ e.g. from Linux-x86 ABI, since structs are already padded to the next aligned size. At least for the alignments an LCM monoid would work.