Const versions of sizeOf and alignment (Was: add `Proxy`fied versions of `bitSizeMaybe` and `finiteBitSize`)
Henning Thielemann
lemming at henning-thielemann.de
Tue Dec 19 09:17:30 UTC 2017
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.
More information about the Libraries
mailing list