首页 > 解决方案 > Haskell 中更整洁的二进制文件处理

问题描述

这是一个普遍的问题,灵感来自我写的一段我不满意的特定代码。我正在使用 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)

你有什么?

标签: haskell

解决方案


我会写

getThing :: Get Thing
getThing = Thing <$> intFrom getWord8 <*> intFrom getWord16 <*> intFrom getWord32
  where
    where intFrom x = toInteger <$> x

您正在寻找的魔法被称为sequence,但您不能将IO Word8,IO Word16IO Word32放在同一个列表中:

getThing :: Get Thing
getThing = do
  [laaa, lbbb, lccc] <- sequence [toInteger <$> getword8, toInteger <$> getword16, toInteger <$> getWord32]
  return $ Thing laaa lbbb lccc

推荐阅读