[Haskell-beginners] More Deserialization Woes

Benjamin Edwards edwards.benj at gmail.com
Thu Jul 1 07:03:39 EDT 2010


It's the type signature of hGet that is your undoing. it returns IO
ByteString, and then you are trying to apply a pure function to that. You
need to lift the pure function into the IO monad.

On 1 July 2010 12:55, Tom Hobbs <tvhobbs at googlemail.com> wrote:

> Hi guys,
>
> Thanks for all the previous help I'm having with serialization in Haskell,
> I couldn't have gotten as far as I have without the help from this group.
> Many thanks!
>
> Now I've put you in a good mood, maybe you can help me with my latest
> problem... :-)
>
> I have the following code which reads strings from a handle;
>
> import qualified Data.ByteString.Lazy.UTF8 as UTF
>
> readNames 0 _ = []
> readNames n h = do
>                            length <- fmap (fromIntegral . runGet
> getWord32be) $ L.hGet h 4
>                            name <- L.hGet h length
>                            (UTF.toString name) : readNames (n-1) h
>
> Where n is the number of names remaining to read and h is the handle to the
> stream that I'm reading from. It is my intention that this function would
> return a [String] of all the names. I'm sure further explainations probably
> aren't necessary, but just in case;
>
> - "length" becomes equal to some number (represented by four bytes) which
> describes the length of the string to read
> - "name" becomes the string I'm trying to read
> - Then I add that String to the list and go again
>
> But the problem I'm getting is this;
>
> Couldn't match expected type `[a]' against inferred type `IO b'
> In a stmt of a 'do' expression:
>                            length <- fmap (fromIntegral . runGet
> getWord32be) $ L.hGet h 4
> In the expression:
>                            do { length <- fmap (fromIntegral . runGet
> getWord32be)
>                            $ L.hGet h 4;
>                            name <- L.hGet h length;
>                            (UTF.toString name) : readNames (n - 1) h }
>
> In the definition of `readNames':
>                            readNames n h
>                            = do { length <- fmap (fromIntegral . runGet
> getWord32be)
>                            $ L.hGet h 4;
>                            name <- L.hGet h length;
>                            (UTF.toString name) : readNames (n - 1) h }
>
> I (think I) understand what the message is saying, but not why it's
> occurring. I read the documentation as "UTF8.tostring" essentially rips the
> [Char] out of the ByteString and returns that, so where does the "IO b" come
> into it? Is it complaining because the reads from the handle are IO
> operations and it's expecting me to use the IO monad somewhere? What i want
> to be able to do is do the IO stuff inside the monad, but end up with a
> [String] which I can then use in a pure function.
>
> RWH and Learn You A Good Haskell all cover some stream reading, but their
> examples are to different from what I'm trying to do that I'm getting stuck.
>
> Any pointers are very gratefully accepted.
>
> Many thanks,
>
> Tom
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20100701/7122d4c0/attachment-0001.html


More information about the Beginners mailing list