Newbie question

Robert Dockins robdockins at fastmail.fm
Sun Jan 9 08:48:27 EST 2005


comments inline...

> module Main
> 	where
> 
> import IO
> 
> main = do
> 	hSetBuffering stdin LineBuffering
> 	words <- askForNumbers
> 	printWords words
> 	map read words
> 	putStrLn "The sum is"
> 	foldl (+) 0 words

as you noted "map read words" is a problematic line.  The problem that
GHC tells you about is that "map read words" creates a value of type 
(Read a) => [a], where but each line in an IO do block needs to have
type IO a.  THe "foldl (+) 0 words" line has the same problem; it's not
an IO value.  A trick you can use is to use "let" to bind a pure value
inside a do block, see below.

I seems to me that you are thinking that "map read" will alter "words"
from a list of Strings to a list of Ints.  This is a fundamental no-no
in a pure functional language like Haskell.  What you want is to create
a new list of integers from your "words" list.  The following changes
makes your program work.

main = do
        hSetBuffering stdin LineBuffering
        words <- askForNumbers
        printWords words
        --map read words
	let ints = map read words
        putStrLn "The sum is"
        --foldl (+) 0 words
	putStrLn (show (foldl (+) 0 ints))

> askForNumbers = do
> 	putStrLn "Please enter a number:"
> 	text <- getLine
> 	if text == ""
> 		then return []
> 		else if text == "0"
> 			then
> 				return []
> 			else do
> 				rest <- askForNumbers
> 				return (text : rest)

This is pretty verbose and (IMO) hard to read. I'd probably write it
this way:

askForNumbers = do
    putStrLn "Pleas enter a number:"
    text <- getLine
    case text of
       ""  -> return []
       "0" -> return []
       _   -> askForNumbers >>= return . (text:)


> printWords [] = putStrLn "EOL"
> printWords (h : t) = do
> 	putStrLn h
> 	printWords t

This could also be more succinct with "sequence_", although increased
redability is arguable.

printWords x = sequence_ (map putStrLn x) >> putStrLn "EOL"







More information about the Glasgow-haskell-users mailing list