Fwd: [Haskell-beginners] More Deserialization Woes

Tom Hobbs tvhobbs at googlemail.com
Tue Jul 6 06:06:53 EDT 2010


On Tue, Jul 6, 2010 at 10:42 AM, Daniel Fischer <daniel.is.fischer at web.de>wrote:

> Nevertheless, IO (Maybe [String]) is, I believe, the appropriate type.
>

I accept that you guys have most likely forgotten more about Haskell than I
know, but can you explain to me why this is the appropriate type?

Note to self: I think I've got the answer to this at the end of this email!


>
> >
> > However, the result of "IO [Just "a", Just "b", Nothing, Nothing]" would
> > signify that communication failed halfway through and would not make
> > sense in my context.  This is what the advice seems to be suggesting I
> > write.  But in this case, I'd prefer to return "Nothing" to signify that
> > a problem occurred.
>
> You can do that by applying sequence (at the type [Maybe String] -> Maybe
> [String]).
>
> Say you have
>
> ping0 :: args -> IO [Maybe String]
>
> then you'd use
>
> ping :: args -> IO (Maybe [String])
>  ping = fmap sequence ping0
>

Okay, I've looked at the definition of sequence in Prelude and I think I
understand what's going on.  I need to experiment with it first before I
fully get it.

So if ping0 returns IO [Just "a", Just "b", Nothing] then then what would
ping return?  IO (Just ["a", "b", ?]).  Nevermind, I can play with that and
work it out later.

Thinking to my requirement I think I'd want something more like;

ping :: args -> IO (Maybe [String])
ping args = fmap f ps
                 where
                 ps = ping0 args
                 f | Nothing `elem` ps = Nothing
                   | otherwise             = fmap sequence ps

Or would I get this behaviour for free straight from the use of sequence?


> >
> > Is it possible, to extract the values out of the IO monad so it can be
> > used in pure functions.
>
> Yes, but you needn't (and shouldn't in general).
>
>
Again, what is the why?

My theory is that I want to get [String] from ping, and then (possibly) do
lots of other things with it that don't require any kind of IO.  But maybe
that's not true and I need to think a bit harder about what the caller is
likely to do with the result from ping.  In terms of performance (memory
footprint, speed of execution, etc) does "carrying around the IO monad" make
much of a difference?

<insert five minute reflective pause here>

You're right.  I don't need to pull the [String] out of the IO monad.
 Suprise, suprise, the general pattern is appropriate in my case.  Something
clicked in my head when I re-read "pureStuff someValues" - this time is was
a good click though!

Please understand, I'm challenging you on the answers because I don't
understand them, not because I think they're wrong!  :-)

Thanks again for the very quick and helpful answers!

Tom



> The general pattern is
>
> main = do
>    someValues <- getDataIOAction
>    let otherValues = pureStuff someValues
>    outputIO otherValues
>
> >
> > For example, once ping has returned it's Maybe [IO String], I would like
> > to be able to create another function such as;
> >
> > purePing :: String -> PortNumber -> Maybe [String]
> > purePing a p = removeIOMonad (ping a p)
> >                       where
> >                       removeIOMonad Nothing = Nothing
> >                       removeIOMonad []    = Just []
> >                       removeIOMonad (x:xs)    = clevelDropIOMagic x :
> > removeIOMonad xs
> >
> > ...or something...
> >
> > Once the IO [String] has been read from the stream, no further IO is
> > necessary, so any other function should be able to just use the list and
> > not worry about the IO stuff.
> >
> > Again my questions are, Is this an okay thing to do, or is my
> > design/idea very, very wrong?
> >
> > Thanks again for the help,
> >
> > Tom
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20100706/baac6a92/attachment-0001.html


More information about the Beginners mailing list