Take the 2-minute tour ×

What is a best approach to get rid of a boilerplate code that serializes/deserializes binary data in Haskell, taking endianness into account? I.e., given this struct:

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

And derived Data.Binary.Binary type class instance:

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

decode stream :: Foobar treats the data as big endian.

Obvious way is to use getWord16le/getWord32le functions, but it involves lots of manual work (which could be automatically and nicely done by Template Haskell coupled with derive).

Perhaps, parametrized types are the solution?

share|improve this question
Aren't the pre-declared instances for Binary always big endian? Working with both big and little endian looks like a recipe for inscrutable errors. If you want to write and parse data in a pre-existing little endian binary format, I'd recommend you avoid making instances of Binary and write a parser and serializer directly without type classes. –  stephen tetley Nov 14 '11 at 18:49
add comment

2 Answers

up vote 7 down vote accepted

How about defining little-endian newtypes for words?

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

Then deriving Binary for the definition

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

should do the right thing.

share|improve this answer
It worked - thanks! Also, GeneralizedNewtypeDeriving is very helpful in this case. –  NikitaBaksalyar Nov 14 '11 at 19:28
add comment

You can define a typeclass for different Word types, such as:

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

instance BinaryEndian Word16 where
   getEndian = getWord16le
   putEndian = putWord16le


That would make TH code perhaps a little easier to write.

share|improve this answer
add comment

Your Answer


