
On 6/23/06, Geoffrey King
I have been work my way through "Haskell The Craft of Functional Programming", all was fine until IO (chapter 18). That is causing me bafflement.
I am trying to write a totally trivial program that reads a series of integers from the console until it gets a zero, then returns the series of integers as a list.
I am down to randomly editing my code, never a good sign. Any clues would be appreciated, My code so far, which clear doesn't work, is: getInt :: IO Int getInt = do putStr "Enter number (zero to quit)" line <- getLine return (read line :: Int)
I haven't tested your code or my proposed changes, but let me step through what you have and offer up explanations of what I think is going wrong. So here, things look pretty good with getInt. getInt has type IO Int, which makes sense because you do some work in the IO monad construct a value and return it. Since you can't escape the IO monad, getInt returns an Int which is wrapped up in the IO monad.
anIntList :: [Int] anIntList = do let n = getInt if n == 0 then return [] else return (n : anIntList)
Okay, so lets start with the let. What is the type of n? Well, it's IO Int because that's the type of getInt. But, IO Int isn't a number so you can't do the test in the if. Otherwise, your code looks pretty good.
ps: even a simple version that returns an Int i can't get to work. anInt :: Int anInt = do n <- getInt return n
Now you're getting closer. But, you do work in the IO monad and construct a value and return it, so your type signature must be wrong. It must be the case that anInt :: IO Int. I see here that you know how to grab 'unwrap' a value in the IO monad and work with it (the line, n <- getInt), you should try doing this above where you have 'let n = getInt'. You may also want to read these fine web pages: http://www.haskell.org/hawiki/MonadsAsContainers http://www.nomaware.com/monads/html/index.html You're so close, I expect you'll have it figured out before I can hit send :) HTH, Jason