在Haskell中使用Data.Binary.Get解析简单的二进制文件

时间:2011-10-26 16:55:39

标签: haskell binary

我试图用Data.Binary.Get monad在Haskell中解析一个简单的二进制文件。

我的代码的简化版本如下所示:

data MsgString = Definition_msg {
      msg_no        :: Word16
    } deriving (Show)

parseDef :: Get MsgString
parseDef = do
    msg_no   <- getWord16le
    return $ Definition_msg msg_no

parseMain :: Get [MsgString]
parseMain =  do
      bit <- getWord8
      msg <- parseDef
      return msg:parseMain

我得到的错误如下:

Prelude> :l example.hs 
[1 of 1] Compiling Main             ( example.hs, interpreted )

example.hs:23:17:
    Couldn't match expected type `[m MsgString]'
           against inferred type `Get [MsgString]'
    In the second argument of `(:)', namely `parseMain'
    In the expression: return msg : parseMain
    In the expression:
        do { bit <- getWord8;
             msg <- parseDef;
               return msg : parseMain }
Failed, modules loaded: none.

谁能看到我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:3)

问题是你的最后一行,解析为:

(return msg) : parseMain

但这确实不是唯一的问题。当你真的只想要一个Get [MsgString]时,parseMain的类型为[MsgString],所以你必须首先运行monadic动作:

parseMain :: Get [MsgString]
parseMain =  do
    bit <- getWord8
    msg <- parseDef
    rest <- parseMain
    return (msg : rest)

请注意,这将获得MsgString的无限列表,并且不会在没有例外的情况下终止。也许您打算使用if语句来保护递归调用parseMain