
Hello I am trying to figure out the best interface to binary parser and pretty printing combinators for network protocols. I am trying to find the most natural syntax to express these parsers in Haskell and would like opinions and new ideas. As an example I will use a protocol with the following packet structure: 0 message-id 4 sender-id 8 receiver-id 12 number of parameters 16 parameters. Each parameter is prefixed by 32bit length followed by the data. We will use the following Haskell datatype: data Packet = Packet Word32 Word32 Word32 [FastString] 1) Simple monadic interface getPacket = do mid <- getWord32BE sid <- getWord32BE rid <- getWord32BE nmsg<- getWord32BE vars<- replicateM (fromIntegral nmsg) (getWord32BE >>= getBytes) return $ Packet mid sid rid nmsg vars putPacket (Packet mid sid rid vars) = do mapM_ putWord32BE [mid, sid, rid, length vars] mapM_ (\fs -> putWord32BE (length fs) >> putBytes fs) vars This works but writing the code gets tedious and dull. 2) Using better combinators packet = w32be <> w32be <> w32be <> lengthPrefixList w32be (lengthPrefixList w32be bytes) getPacket = let (mid,sid,rid,vars) = getter packet in Packet mid sid rid vars putPacket (Packet mid sid rid vars) = setter packet mid sid rid vars Maybe even the tuple could be eliminated by using a little of TH. Has anyone used combinators like this before and how did it work? 3) Using TH entirely $(getAndPut 'Packet "w32 w32 w32 lengthPrefixList (w32 bytes)") Is this better than the combinators in 2)? Also what sort of syntax would be best for expressing nontrivial dependencies - e.g. a checksum calculated from other fields. 4) Using a syntax extension Erlang does this with the bit syntax (http://erlang.se/doc/doc-5.4.8/doc/programming_examples/bit_syntax.html) and it is very nifty for some purposes. getPacket = do << mid:32, sid:32, rid:32, len:32 rest:len/binary >> ... The list of lists gets nontrivial here too... - Einar Karttunen