这是一个普遍的问题,受到我写的我不满意的一段特定代码的启发。我正在使用Data.Binary.Get从二进制文件中获取一些数据。一些代码看起来像这样
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
“ getThing”功能确实很长。我希望有一种不错的方法来执行类似以下的伪代码或什至更简洁的操作。
[laaa, lbbb, lccc] <- MAGIC [getword8, getword16, getWord32] >>= \x -> return (toInteger x)
你有什么?
答案 0 :(得分:4)
我会写
getThing :: Get Thing
getThing = Thing <$> intFrom getWord8 <*> intFrom getWord16 <*> intFrom getWord32
where
where intFrom x = toInteger <$> x
您正在寻找的魔法称为sequence
,但是您不能将IO Word8
,IO Word16
和IO Word32
放在同一列表中:
getThing :: Get Thing
getThing = do
[laaa, lbbb, lccc] <- sequence [toInteger <$> getword8, toInteger <$> getword16, toInteger <$> getWord32]
return $ Thing laaa lbbb lccc