[Haskell-cafe] Data.Binary suboptimal instance
Khudyakov Alexey
alexey.skladnoy at gmail.com
Fri May 22 17:36:24 EDT 2009
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
More information about the Haskell-Cafe
mailing list