
Hi again all, I've got a somewhat functioning new Binary module for GHC which supports bit writes. I've written a small test script to make sure simple things work...it essentially looks like this: data BinItem = ByteItem Word8 | BitItem Int Word8 -- num_bits bits | FlushItem -- flush byte | forall a . (Eq a, Binary a, Show a) => BinaryItem a -- some arbi trary data | forall a . (Eq a, Show a) => PutItem a (BinHandle -> a -> IO ()) (BinHandle -> IO a) on which Eq is defined (I use unsafePerformIO to cast the forall'd elements). then we have test functions which essentially open up a binMem or a binIO and write a list of BinItems to it, then read them back. We can then check if what we read back is the same as what we wrote. The tests I have run are: byteTest = map ByteItem [1,2,3,4,5] bitTest1 = [BitItem 3 6, FlushItem] bitTest2 = [BitItem 3 6, BitItem 4 9, BitItem 1 0, FlushItem] bitTest3 = [BitItem 6 10, BitItem 6 10, FlushItem] flushTest1 = [BitItem 3 6, FlushItem, BitItem 4 9, BitItem 1 0, FlushItem] flushTest2 = [ByteItem 1, FlushItem, FlushItem, FlushItem, FlushItem, ByteItem 2 , FlushItem] comboTest1 = [ByteItem 5, BitItem 3 6, FlushItem, ByteItem 9, BitItem 4 9, BitIt em 1 0, FlushItem, ByteItem 84, BitItem 3 2, FlushItem] comboTest2 = [ByteItem 5, BitItem 3 6, ByteItem 9, BitItem 7 9, BitItem 4 0, Byt eItem 84, BitItem 3 2, FlushItem] maybeTest1 = [BinaryItem (Just 5::Maybe Int), BinaryItem (Nothing::Maybe Int), B inaryItem (Just 0::Maybe Int), BinaryItem (Just 1::Maybe Int), BinaryItem (Nothi ng :: Maybe Int), FlushItem] maybeTest2 = map (\i -> PutItem i putMaybeInt getMaybeInt) [Just 5, Nothing, Jus t 0, Just 1, Nothing] ++ [FlushItem] Which all work fine. putMaybeInt uses a bit to put the Just/Nothing, while the normal Binary instance for Maybe uses a byte. ...this brings up another question...since we don't have named instances, I'm thinking of separating the actual instance definitions into two modules, one which uses bit-based instances and one which uses byte-based instances. You could then import whichever makes more sense for your application. The problem with this is that sometimes it might make sense to use bytes in one aspect and bits in another. Another solution would be to extend the Binary class to: class Binary a where put_ :: BinHandle -> a -> IO () put :: BinHandle -> a -> IO (Bin a) get :: BinHandle -> IO a putWithBits_ :: BinHandle -> a -> IO () putWithBits :: BinHandle -> a -> IO (Bin a) getWithBits :: BinHandle -> IO a so that each instance specifies how to write itself both with bits and bytes. of course they could default off eachother, so the user only has to write one put and one get if they're lazy. Thoughts? - Hal