
Simon,
I'd be delighted if someone would add support for bits to GHC's Binary library (to get a fair comparison) and did some measurements. It may be that there's no need to add an abstraction layer to provide support for both bits and bytes.
This doesn't seem like an awful lot of work, and if it would help getting Binary into the hier libs, I'd be more than happy to do it. Given Eray's comments, it might turn out to be faster. Simon: I have a version of the GHC Binary module, but I know that I've mucked around with it quite a bit. I've also got the one off of cvs in ghc/compiler/utils/Binary.hs, which would probably be a better (read: safer) starting place. Basically we want to add two functions: putBit :: BinHandle -> Bool -> IO () getBit :: BinHandle -> Bool -> IO () It seems that in order to accomplish this, the BinMem constructor needs to be augmented with two fields, one Word8 which contains bits which have been "put" but haven't yet been written to the array and another Word8 which stores the current bit position we are at in this Word8. Then, the work comes down mostly to bit-twiddling in the putWord8 and putBit functions (putBit being the simpler of the two). It seems the BinIO constructor would require basically the identical thing, which means perhaps this stuff should be added to the BinHandleState variable. It might be wise also to add a function like: flushByte :: BinHandle -> IO () which essentially moves you forward to the next byte position. Of course both reading and writing would have to call this at the same type. There's a concern that if you only write, say, 2 of the last 8 bits, this won't actually get written unless you call flushByte. I don't know how this was handled in the NHC version; perhaps just require the user to call flushByte at the end if they're worried about such behavior? - Hal