[Haskell-cafe] so how does one convert an IO a into an a ?

Paul Hudak paul.hudak at yale.edu
Fri Jul 9 10:41:48 EDT 2004


Judging from a previous message I'm not sure if you're still using SOE, 
but one of the things I tried to do is introduce IO without mentioning 
monads at all, and if you read chapter 3 (especially section 3.1) you 
will see that that's the case.  To those who have had imperative 
programming experience, I think that section 3.1 should not present any 
problems.

But it sounds as if you've gotten past that, since you quoted something 
from chapter 18, where the "mysteries" of IO are revealed in gory 
detail.  It looks like lots of people have given you good advice, but 
I'll throw in one more idea about how to "convert an IO Int into an 
Int".  Although, as many have pointed out, you can't really do this in a 
technical sense, you can get the effect that you want as follows:

Suppose you have a function foo of type IO Int, and you wish to apply a 
function bar of type Int -> T to the value you get from foo (T is some 
result type).  Then all you have to do is this:

 > do i <- foo
 >    return (bar i)

This is what people meant by "writing a little monadic scaffolding" to 
achieve what you want.  The function bar is a pure function that does 
not involve IO at all.  It may involve dozens of page of code, but you 
need the two lines of "scaffolding" above in order to invoke it.

Now, in the end, you might say that we haven't achieved much, because 
the above expression has type IO T, so all we've really done is convert 
an IO Int into an IO T.  Quite true!  That's why most of the people who 
responded to your email eventually wrote something like:

 > do i <- foo
 >    putStr (show (bar i))

or whatever, in order to actually generate some useful output.  Indeed, 
that useful output might also include writing to a file, displaying some 
graphics, etc.

I hope this helps,

   -Paul


Crypt Master wrote:
> Hi
> 
> Thanks for your help so far, but I am still not getting this IO stuff. 
> After reading your previous help and reading several articles on it I 
> still cant phathom how you convert the IO Int into an Int.
> 
> One person mentioned how random just returns an interative program which 
> when eveluated returns the Int. Also from the school of expression book 
> he says " The right way to think of (>>=) above is simply this: It 
> "Executes" e1 ..." in relation to "do pat <- e1 ...".
> 
> so I have this:
> 
> <code>
> rollDice :: IO Int
> rollDice = getStdRandom (randomR (1,6))
> 
> rl :: [Int]
> rl = [ (getRndNum x) | x <- [1..] ]
> 
> getRndNum :: Int -> Int
> getRndNum x = do n <- rollDice
>               return n
> </code>  *PS Pretend return is correctly aligned under n. dont what 
> ahppens in copy and paste*
> 
> now my understanding therefore is that "do n <- rollDice" should execute 
> the the itererative program returned by rollDice. So now n should be my 
> Int since IO Int was a program which when evaluted returns an Int ?
> 
> However this is what haskell thinks of my thoery:
> 
> *** Term           : getRndNum
> *** Type           : Int -> IO (Maybe Int)
> *** Does not match : Int -> Int
> 
> So I am still in IO Int land despite having used the >>= in the do 
> syntax. Worse Still I am in IO (Maybe Int) land. Monads within Monads.
> 
> In yours, and many other examples I found online, the results are always 
> passed to print which seems to know how to deal with an IO Int. Is this 
> specially coded or overloaded or something ?
> 
> There are plenty of examples which use return like so:
> 
> do k <- getKey w
>    return k
> 
> which is what I tried above to no avail.
> 
> It seems awefully complicated just to get hold a simple Int, but 
> naturally complicity is directly related to ones understanding. Mine is 
> sumewhat lacking ... any help would be appreciated.
> 
> Thanks,
> 
> S




More information about the Haskell-Cafe mailing list