Here is the code: https://github.com/EarlGray/haskell-snippets/blob/master/ext2hs/Ext2.hs
My problem is that it is quite painful to make large Haskell "records" and deserialize a binary layout with Data.Binary.Get
manually like this:
instance Binary Superblock where
get = binGetSuperblock
binGetSuperblock = do
uint13 <- replicateM 13 getWord32le
ushort6 <- replicateM 6 getWord16le
uint4 <- replicateM 4 getWord32le
ushort2 <- replicateM 2 getWord16le
return Superblock {
sInodesCount = uint13 !! 0, sBlocksCount = uint13 !! 1,
sReservedBlocksCount = uint13 !! 2, sFreeBlocksCount = uint13 !! 3,
sFreeInodesCount = uint13 !! 4, sFirstDataBlock = uint13 !! 5,
sLogBlockSize = uint13 !! 6, sLogClusterSize = uint13 !! 7,
sBlocksPerGroup = uint13 !! 8, sClustersPerGroup = uint13 !! 9,
sInodesPerGroup = uint13 !! 10, sMountTime = uint13 !! 11,
sWriteTime = uint13 !! 12,
sMountsCount = ushort6 !! 0, sMaxMountsCount = int (ushort6 !! 1),
sMagic = ushort6 !! 2, sState = ushort6 !! 3,
sErrors = ushort6 !! 4,
sLastCheckTime = uint4 !! 0, sCheckInterval = uint4 !! 1,
sCreatorOS = uint4 !! 2, sRevLevel = (uint4 !! 3, ushort6 !! 5),
sDefaultResUID = ushort2 !! 0, sDefaultResGID = ushort2 !! 1,
sDynRev = Nothing,
sPrealloc = Nothing,
sJournaling = Nothing
}
(this is ext2fs superblock structure).
First of all, I would like to make binary layout as much declarative as possible, abstracting away those ugly sequences of getWord32le
in Get
monad with temporary fields. I want something like my python code, where binary fields are unpacked to a map according to a struct
format string
The second thing I need is a more concise and more clear way for initializing a large Haskell record (creating a lot of temporary named values in the monad is pain).
One way I think of is to read binary fields into a heterogeneous map forall a. BinaryField a => Map String a
, accessing each value by its name and pre-extracting most used ones to Haskell.
Perhaps Template Haskell and code generation from a declarative format may help, but I have no experience with TH yet.
I would be glad to hear any suggestions or hints about a more idiomatic way (are there any relevant tools?) or about the code in general (though it's just my learning code and it's very incomplete at the moment).