Если вы действительно хотите, чтобы это было похоже на структуру из четырех слов32, вы можете использовать строгие / распакованные поля:
data MyType = MyType { a :: {-# UNPACK #-} !Word32
, b :: {-# UNPACK #-} !Word32
, c :: {-# UNPACK #-} !Word32
, d :: {-# UNPACK #-} !Word32 }
deriving (Show)
Тогда, давайте определим пару функций с битами:
mask :: Bits a => Int -> a
mask count = (1 `shiftL` count) - 1
bitRange :: Bits a => Int -> Int -> a -> a
bitRange low count val = (val `shiftR` low) .&. mask count
Теперь вы можете просто написать 128-битные методы доступа для этого типа:
from128 :: Integer -> MyType
from128 val = MyType (bitsFrom 0)
(bitsFrom 32)
(bitsFrom 64)
(bitsFrom 96)
where
bitsFrom i = fromIntegral (bitRange i 32 val)
to128 :: MyType -> Integer
to128 (MyType a b c d) =
foldl' (.|.) 0 [
bitsTo a 0,
bitsTo b 32,
bitsTo c 64,
bitsTo d 96
]
where
bitsTo val i = fromIntegral val `shiftL` i
Для полей a b c d
вы можете просто использовать fclabels . Вы также можете создать биективный функтор fclabel (:<->:)
:
myType128 :: MyType :<->: Integer
myType128 = to128 :<->: from128