
On Friday 22 May 2009 23:34:50 Henning Thielemann wrote:
So lately I've been working on a little program to generate trippy graphics. (Indeed, some of you may remember it from a few years back...) Anyway, getting to the point, I just restructured my program. As part of the restructuring, I got rid of all the jiggery-pokery with Data.Array.Storable and so forth and decided to use Data.Binary.
My first problem was quite simple. I want to write a program that reads an item from the input file, processes it, writes it to the output file, and repeats until the input file is empty. Data.Binary doesn't appear to provide any obvious way to do this. You can't be in the Get and Put monads simultaneously, and I can't figure out how to interleave them.
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:
process :: [Foo] -> [Bar]
foo = readFile name >>= writeFile out . encodeStream . process . decodeProcess
There is a code. It is fast and worked for me without a problem.
-- | Decode records in repetition decodeStream :: Binary a => ByteString -> [a] decodeStream = runGet (getStream get)
-- | Encode list of records as bytestring encodeStream :: Binary a => [a] -> ByteString encodeStream = runPut . putStream put
-- | Read list of values from bytestring until it ends. getStream :: Get a -> Get [a] getStream getter = do empty <- isEmpty if empty then return [] else do x <- getter xs <- getStream getter return (x:xs)
-- | Write list of values. putStream :: (a -> Put) -> [a] -> Put putStream f = mapM_ f
-- Khudyakov Alexey