什么是在Haskell中解码/编码二进制小端数据的更好方法?

时间:2011-11-14 12:15:57

标签: haskell

什么是最好的方法来摆脱在Haskell中序列化/反序列化二进制数据的样板代码,考虑到字节序?即,给出这个结构:

data Foobar = Foobar { foo :: Word16, bar :: Word32 }

派生Data.Binary.Binary类型类实例:

instance Binary Foobar where
  get = do
    foo <- get
    bar <- get
    return $ Foobar foo bar

decode stream :: Foobar将数据视为大端。

明显的方法是使用getWord16le / getWord32le函数,但它涉及大量的手工工作(可以通过模板Haskell与derive一起自动完成)。

也许,参数化类型是解决方案?

2 个答案:

答案 0 :(得分:8)

如何为单词定义little-endian newtypes?

newtype LWord16 = LWord16 { unLWord16 :: Word16 }
newtype LWord32 = LWord32 { unLWord32 :: Word32 }
instance Binary LWord16 where get = LWord16 <$> getWord16le
instance Binary LWord32 where get = LWord32 <$> getWord32le

然后为定义导出Binary

data Foobar = Foobar { foo :: LWord16, bar :: LWord32 }

应该做正确的事。

答案 1 :(得分:2)

您可以为不同的Word类型定义类型类,例如:

class BinaryEndian a where
   getEndian :: Get a
   putEndian :: a -> Put

instance BinaryEndian Word16 where
   getEndian = getWord16le
   putEndian = putWord16le

这会使TH代码更容易编写。