Problems with one of my first examples

Hello, I have started reading "Yet Another Haskell Tutorial" by Hal Daum´e III which can be found here http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf One of the early examples in section 3.8 pg. 35 is this askForWords = do putStrLn "Please enter a word:" word <- getLine if word == "" then return [] else do rest <- askForWords return (word : rest) I want to print the returned list and everything I try fails. I have tried the following: printList l = if length l >= 1 then do putStrLn (head l) printList (tail l) else putStrLn("") f = printList askForWords and I get Expression : printList askForWords *** Term : askForWords *** Type : IO [[Char]] *** Does not match : [[Char]] ************************************* The exercise right below this asks for a very slight modification to read numbers instead. However, I am confused about how to convert strings to numbers. If I type in the hugs interactive console read "5" + 3 --> 8 -- ok perfect However read "5" gives ERROR - Unresolved overloading *** Type : Read a => a *** Expression : read "5" Yet page 33 of the tutorial has the following code: doGuessing num = do putStrLn "Enter your guess:" guess <- getLine let guessNum = read guess -- ok in let stmt, but not at repl prompt? Anyway I take the info that has been presented and create this function: askForNumbers = do hSetBuffering stdin LineBuffering putStrLn "Give me a number (or 0 to stop)" numStr <- getLine let num = read numStr if num == 0 then return [] else do rest <- askForNumbers return (num : rest) However, when I try to use it, like say map sqrt askForNumbers ERROR - Type error in application *** Expression : map sqrt askForNumbers *** Term : askForNumbers *** Type : IO [Integer] *** Does not match : [a] ********************************************************* Is there a way to write printList to handle Strings or numbers? Or should I write printList (map show askForNumbers) Thanks, Jeff

On Mon, Dec 15, 2008 at 12:17 PM, Jeff C. Britton
Hello,
I have started reading "Yet Another Haskell Tutorial" by Hal Daum´e III which can be found here http://www.cs.utah.edu/~hal/docs/daume02yaht.pdfhttp://www.cs.utah.edu/%7Ehal/docs/daume02yaht.pdf
One of the early examples in section 3.8 pg. 35 is this
askForWords = do putStrLn "Please enter a word:" word <- getLine if word == "" then return [] else do rest <- askForWords return (word : rest)
I want to print the returned list and everything I try fails.
I have tried the following:
printList l = if length l >= 1 then do putStrLn (head l) printList (tail l) else putStrLn("")
f = printList askForWords
and I get Expression : printList askForWords *** Term : askForWords *** Type : IO [[Char]] *** Does not match : [[Char]]
I believe one of the following will work for you: f = askForWords >>= printList f = do words <- askForWords printList words
************************************* The exercise right below this asks for a very slight modification to read numbers instead.
However, I am confused about how to convert strings to numbers. If I type in the hugs interactive console read "5" + 3 --> 8 -- ok perfect
However read "5" gives ERROR - Unresolved overloading *** Type : Read a => a *** Expression : read "5"
Yet page 33 of the tutorial has the following code: doGuessing num = do putStrLn "Enter your guess:" guess <- getLine let guessNum = read guess -- ok in let stmt, but not at repl prompt?
The problem here is type inference. The statement read "5" has type "(Read a) => a", which basically means anything that implements the class "Read." When you do read "5" + 3, the read "5" gets the type of the 3. I assume that in the latter case, you use the expression guessNum in a way later on that the compiler can infer its type.
Anyway I take the info that has been presented and create this function: askForNumbers = do hSetBuffering stdin LineBuffering putStrLn "Give me a number (or 0 to stop)" numStr <- getLine let num = read numStr if num == 0 then return [] else do rest <- askForNumbers return (num : rest)
However, when I try to use it, like say
map sqrt askForNumbers
ERROR - Type error in application *** Expression : map sqrt askForNumbers *** Term : askForNumbers *** Type : IO [Integer] *** Does not match : [a]
Similar to above, try this: do nums <- askForNumbers map sqrt nums
*********************************************************
Is there a way to write printList to handle Strings or numbers? Or should I write printList (map show askForNumbers)
Note: you should probably do this using mapM_, but for simplicity, I'll do it using explicit recursion: printList [] = putStrLn "" -- or return () if you don't want the extra blank line printList (x:xs) = do putStrLn (show x) printList xs If you have any questions about how these worked, let me know! Michael

Thanks, Michael. Ok, I understand most of what you did, but ... do nums <- askForNumbers; map sqrt nums ERROR - Type error in final generator *** Term : map sqrt nums *** Type : [Integer] *** Does not match : IO a do nums <- askForNumbers; printList nums -- works fine Thanks, Jeff ------------------------------------------------------------- Hello, I have started reading "Yet Another Haskell Tutorial" by Hal Daum´e III which can be found here http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf One of the early examples in section 3.8 pg. 35 is this askForWords = do putStrLn "Please enter a word:" word <- getLine if word == "" then return [] else do rest <- askForWords return (word : rest) I want to print the returned list and everything I try fails. I have tried the following: printList l = if length l >= 1 then do putStrLn (head l) printList (tail l) else putStrLn("") f = printList askForWords and I get Expression : printList askForWords *** Term : askForWords *** Type : IO [[Char]] *** Does not match : [[Char]] I believe one of the following will work for you: f = askForWords >>= printList f = do words <- askForWords printList words ************************************* The exercise right below this asks for a very slight modification to read numbers instead. However, I am confused about how to convert strings to numbers. If I type in the hugs interactive console read "5" + 3 --> 8 -- ok perfect However read "5" gives ERROR - Unresolved overloading *** Type : Read a => a *** Expression : read "5" Yet page 33 of the tutorial has the following code: doGuessing num = do putStrLn "Enter your guess:" guess <- getLine let guessNum = read guess -- ok in let stmt, but not at repl prompt? The problem here is type inference. The statement read "5" has type "(Read a) => a", which basically means anything that implements the class "Read." When you do read "5" + 3, the read "5" gets the type of the 3. I assume that in the latter case, you use the expression guessNum in a way later on that the compiler can infer its type. Anyway I take the info that has been presented and create this function: askForNumbers = do hSetBuffering stdin LineBuffering putStrLn "Give me a number (or 0 to stop)" numStr <- getLine let num = read numStr if num == 0 then return [] else do rest <- askForNumbers return (num : rest) However, when I try to use it, like say map sqrt askForNumbers ERROR - Type error in application *** Expression : map sqrt askForNumbers *** Term : askForNumbers *** Type : IO [Integer] *** Does not match : [a] Similar to above, try this: do nums <- askForNumbers map sqrt nums ********************************************************* Is there a way to write printList to handle Strings or numbers? Or should I write printList (map show askForNumbers) Note: you should probably do this using mapM_, but for simplicity, I'll do it using explicit recursion: printList [] = putStrLn "" -- or return () if you don't want the extra blank line printList (x:xs) = do putStrLn (show x) printList xs If you have any questions about how these worked, let me know! Michael

Am Montag, 15. Dezember 2008 23:26 schrieb Jeff C. Britton:
Thanks, Michael.
Ok, I understand most of what you did, but ...
do nums <- askForNumbers; map sqrt nums
ERROR - Type error in final generator *** Term : map sqrt nums *** Type : [Integer] *** Does not match : IO a
There's another one lurking there, :t sqrt sqrt :: (Floating a) => a -> a but Integer is not a member of class Floating. The one displayed says that you must have an IO-action in your do-block, not a plain list of numbers. do nums <- askForNumbers printList $ map (sqrt . fromInteger) nums works, or printList . map (sqrt . fromInteger) =<< askForNumbers
do nums <- askForNumbers; printList nums -- works fine
Thanks,
Jeff
------------------------------------------------------------- Hello,
I have started reading "Yet Another Haskell Tutorial" by Hal Daum´e III which can be found here http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf
One of the early examples in section 3.8 pg. 35 is this
askForWords = do putStrLn "Please enter a word:" word <- getLine if word == "" then return [] else do rest <- askForWords return (word : rest)
I want to print the returned list and everything I try fails.
I have tried the following:
printList l = if length l >= 1 then do putStrLn (head l) printList (tail l) else putStrLn("")
f = printList askForWords
and I get Expression : printList askForWords *** Term : askForWords *** Type : IO [[Char]] *** Does not match : [[Char]]
I believe one of the following will work for you:
f = askForWords >>= printList f = do words <- askForWords printList words
************************************* The exercise right below this asks for a very slight modification to read numbers instead.
However, I am confused about how to convert strings to numbers. If I type in the hugs interactive console read "5" + 3 --> 8 -- ok perfect
However read "5" gives ERROR - Unresolved overloading *** Type : Read a => a *** Expression : read "5"
Yet page 33 of the tutorial has the following code: doGuessing num = do putStrLn "Enter your guess:" guess <- getLine let guessNum = read guess -- ok in let stmt, but not at repl prompt?
The problem here is type inference. The statement read "5" has type "(Read a) => a", which basically means anything that implements the class "Read." When you do read "5" + 3, the read "5" gets the type of the 3. I assume that in the latter case, you use the expression guessNum in a way later on that the compiler can infer its type.
Anyway I take the info that has been presented and create this function: askForNumbers = do hSetBuffering stdin LineBuffering putStrLn "Give me a number (or 0 to stop)" numStr <- getLine let num = read numStr if num == 0 then return [] else do rest <- askForNumbers return (num : rest)
However, when I try to use it, like say
map sqrt askForNumbers
ERROR - Type error in application *** Expression : map sqrt askForNumbers *** Term : askForNumbers *** Type : IO [Integer] *** Does not match : [a]
Similar to above, try this: do nums <- askForNumbers map sqrt nums
*********************************************************
Is there a way to write printList to handle Strings or numbers? Or should I write printList (map show askForNumbers)
Note: you should probably do this using mapM_, but for simplicity, I'll do it using explicit recursion:
printList [] = putStrLn "" -- or return () if you don't want the extra blank line printList (x:xs) = do putStrLn (show x) printList xs
If you have any questions about how these worked, let me know!
Michael _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Jeff C. Britton wrote:
do nums <- askForNumbers; map sqrt nums
ERROR - Type error in final generator *** Term : map sqrt nums *** Type : [Integer] *** Does not match : IO a
Here (map sqrt nums) has type [Integer], so you cannot use it in a do expression for IO. Instead, you have to write something which produces an IO action.
do nums <- askForNumbers; printList nums -- works fine
Here, (printList nums) has type IO (), so it fits into the do expression and everything is fine. If you want to print the list of square roots, you have to say so: do nums <- askForNumbers; printList (map sqrt nums) Tillmann
participants (4)
-
Daniel Fischer
-
Jeff C. Britton
-
Michael Snoyman
-
Tillmann Rendel