haskell - 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)
你有什么?
解决方案
我会写
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
推荐阅读
- python - 基于半一致特征拆分字符串
- forms - Symfony - 需要的个人递归函数 = true 返回 false
- java - Guage 测试自动化框架是否允许在同一个 repo 中使用多种语言?
- python - 如何检查图像切片中是否有 5 个或 6 个复选框?
- selenium - Jenkins Xvfb libcrypto 问题
- laravel - Laravel Nova 模板自定义
- authentication - 如何在创建新用户时修复用户验证插件中的错误?
- asp.net - 为什么请求不会超时?
- java - Why am I getting wrong result with java.sql.Date and PreparedStatement?
- android - 弹出菜单正在累积出现次数(未正确关闭)