Reputation: 185
This is a general question inspired by a particular piece of code I wrote that I'm not happy with. I'm using Data.Binary.Get to grab some data from a binary file. Some of the code looks a bit like this
import Data.Binary.Get
data Thing = Thing
{
aaa :: Integer,
bbb :: Integer,
ccc :: Integer
} deriving (Show)
getThing :: Get Thing
getThing = do
laaa <- getWord8 >>= \x -> return (toInteger x)
lbbb <- getWord16host >>= \x -> return (toInteger x)
lccc <- getWord32host >>= \x -> return (toInteger x)
return $ Thing laaa lbbb lccc
The "getThing" function is really long. I am hoping there is a nice way to do something like the following pseudocode or maybe something even more concise.
[laaa, lbbb, lccc] <- MAGIC [getword8, getword16, getWord32] >>= \x -> return (toInteger x)
What have you got?
Upvotes: 1
Views: 60
Reputation: 665456
I would write
getThing :: Get Thing
getThing = Thing <$> intFrom getWord8 <*> intFrom getWord16 <*> intFrom getWord32
where
where intFrom x = toInteger <$> x
The magic you are looking for is known as sequence
, but you can't put IO Word8
, IO Word16
and IO Word32
in the same list:
getThing :: Get Thing
getThing = do
[laaa, lbbb, lccc] <- sequence [toInteger <$> getword8, toInteger <$> getword16, toInteger <$> getWord32]
return $ Thing laaa lbbb lccc
Upvotes: 4