Fwd: [Haskell-beginners] More Deserialization Woes

Daniel Fischer daniel.is.fischer at web.de
Tue Jul 6 05:42:04 EDT 2010


On Tuesday 06 July 2010 11:15:12, Tom Hobbs wrote:
> Sorry, I meant to send this to the list, rather than just to Stephen
> (sorry for the Spam).
>
> Tom
>
>
> ---------- Forwarded message ----------
> From: Tom Hobbs <tvhobbs at googlemail.com>
> Date: Tue, Jul 6, 2010 at 10:12 AM
> Subject: Re: [Haskell-beginners] More Deserialization Woes
> To: Stephen Tetley <stephen.tetley at gmail.com>
>
>
> Hello again,
>
> I've been reading through various tutorials and they all put IO as the
> outermost monad, like you suggest.  However, I don't think that's what I
> want.
>
> My IO operation is reading from a network stream, not a file, so I want
> a failure halfway through should signify a complete failure.  So, I
> believe that the type signature for my function should be;
>
> ping  :: String -> PortNumber -> Maybe (IO [String])
>
> because the result "Just []" is a valid one and does not signify a
> failure.
>

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

>
> 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

>
> So my first question is; because I want to do something so different
> from the majority of the articles I've read; am I in a niche where my
> requirement makes sense, or does my requirement make no sense - a theory
> that is backed up by the fact that no one else seems to be doing that...
>
> Now, I'm not sure I can get there by myself, since I'm struggling to get
> the right incantation of catching errors but I'll keep plugging away at
> that for a while.
>
> But can someone help me with my next question also.
>
> 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).

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


More information about the Beginners mailing list