
I suppose I should send my reply to the list ...
---------- Forwarded message ----------
From: Antoine Latter
You can! - It's again time to point out that Put shouldn't be a monad, but a monoid. But as it is, Put is a Writer monad on top of the Builder monoid. Better use that Builder monoid directly.
Could you elaborate? I didn't quite understand.
Anyway I had similar problem and simply wrote few functions. They encode/decode values of same type element by element. It's lazy enough so code could be written in following style:
Or you could go for the compromise position, where the list can be part of a complex data structure so you're not relying on EOF to find the end. (warning, I don't have my compiler handy so this may not even typecheck) import Control.Monad import Data.Monoid import Data.Binary.Builder import Data.Binary.Get data ChunkedList a = Cons [a] (ChunkedList a) -- Non-null list | Nil chunkSize = 50 fromList :: [a] -> ChunkedList a fromList [] = Nil fromList xs = let (front,back) = splitAt chunkSize xs in Cons front (fromList back) toList :: ChunkedList a -> [a] toList Nil = [] toList (Cons front back) = front ++ toList back putList :: (a -> Builder) -> [a] -> Builder putList f xs = putChunkedList (fromList xs) where putChunkedList Nil = singleton 0 putChunkedList (Cons front back) = mconcat [ singleton (genericLength front) , mconcat $ map f front , putChunkedList back ] getList :: Get a -> Get [a] getList m = toList `liftM` getChunkedList where getChunkedList = do cLen <- getWord8 case cLen of 0 -> return Nil _ -> Cons `liftM` replicateM (fromIntegral cLen) m `ap` getChunkedList