
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