[Haskell-beginners] Problems with one of my first examples
Michael Snoyman
michael at snoyman.com
Mon Dec 15 15:48:16 EST 2008
On Mon, Dec 15, 2008 at 12:17 PM, Jeff C. Britton <jcb at iteris.com> wrote:
> 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<http://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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20081215/03bfa53c/attachment.htm
More information about the Beginners
mailing list