Fwd: [Haskell-beginners] More Deserialization Woes

Tom Hobbs tvhobbs at googlemail.com
Tue Jul 6 05:15:12 EDT 2010


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.


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.

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.

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


On Thu, Jul 1, 2010 at 1:53 PM, Stephen Tetley <stephen.tetley at gmail.com>wrote:

> Hi Tom
>
> This is bit that is wrong:
>
> ((UTF.toString name) : readNames (n-1) h)
>
>
> You are trying to cons (:) a String onto an IO [String]:
>
> (UTF.toString name) :: String
>
> (readNames (n-1) h) :: IO [String]
>
> (:) :: a -> [a] -> [a]
>
> This is easy mistake to make, I probably still make it myself now and
> again if I'm typing faster than I'm thinking.
>
> As for ping, you are right that the common answer type will be "IO
> (Maybe [String])" i.e.
>
> ping :: String -> PortNumber -> IO (Maybe [String])
>
>
> Generally you will want IO as the outermost (type-) constructor for an
> expression involving IO, this is because you can't 'escape' IO. There
> are some exceptions where IO isn't the outermost type constructor, the
> common one I can think of is you might want to build a list of IO
> actions [IO ()]. You would then commonly pass on this list to evaluate
> it later with mapM_.
>
>
> Neil Mitchell's "IO without (concentrating) on monads tutorial" is a
> very good place to start:
> http://neilmitchell.blogspot.com/2010/01/haskell-io-without-monads.html
>
> Best wishes
>
> Stephen
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20100706/aaface7e/attachment-0001.html


More information about the Beginners mailing list