[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