Newbie question

2005-01-09 Thread Dmitri Pissarenko
Hello!

I am learning Haskell according to the Yet Another Haskell Tutorial by Hal
Daume Ill.

One of the exercises involves

a) asking the user to enter several numbers (while the end of the sequence is
indicated by entering 0)
b) calculate the sum of those numbers.

The program given below tries to do that.

I can read a list of strings. Then, I try to convert the list of strings into
a list of numbers by means of map.

That is, given a list [1,2,3], I want to convert it into [1,2,3].

In GHCi, this is done via

map read [1,2,3]

However, when I apply this same call in my program below, I'm getting
following error when loading the program in GHCi:

error-message
Loading package base ... linking ... done.
Compiling Main ( AskForNumbers.hs, interpreted )

AskForNumbers.hs:10:
Couldn't match `IO' against `[]'
Expected type: IO t
Inferred type: [b]
In the application `map read words'
In a 'do' expression: map read words
Failed, modules loaded: none.
/error-message

Line 10 corresponds to the statement

map read words,

which seems to work in GHCi.

What am I doing wrongly?

Thanks in advance

Dmitri Pissarenko

PS: What follows is my Haskell program.

module Main
where

import IO

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

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)

printWords [] = putStrLn EOL
printWords (h : t) = do
putStrLn h
printWords t
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Newbie question

2005-01-09 Thread Einar Karttunen
Dmitri Pissarenko [EMAIL PROTECTED] writes:
 a) asking the user to enter several numbers (while the end of the sequence is
 indicated by entering 0)
 b) calculate the sum of those numbers.

 ...
 

Here is a corrected version:

 module Main where

 import IO

Delete this.

 main = do
   hSetBuffering stdin LineBuffering

This is extraneous - stdin should be line buffered by default.

   words - askForNumbers
   printWords words
   map read words
   putStrLn The sum is
   foldl (+) 0 words

Here you map read over words and discard the result.
Then you wold over the words and produce an interger,
whereas you should produce an IO value from the do block.

Here is a complete implementation (untested):

main = do 
   words - askForNumbers
   mapM_ putStrLn words
   putStrLn EOL
   let nums = map read words
   print nums
   putStrLn The sum is
   print (foldl (+) 0 nums)

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Newbie question

2005-01-09 Thread Robert Dockins
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





___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Newbie question

2005-01-09 Thread Dmitri Pissarenko
Thanks all for the help!
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: (Stupid?) newbie question

1999-09-01 Thread Sigbjorn Finne (Intl Vendor)

Hi,
 
not a stupid question, just a stupid bug in 4.03 ;-)
 
This has been fixed in the patch available from the
ghc-win32 web page, http://www.dcs.gla.ac.uk/~sof/ghc-win32.html
http://www.dcs.gla.ac.uk/~sof/ghc-win32.html 
 
hth
--sigbjorn

-Original Message-
From: felix [mailto:[EMAIL PROTECTED]]
Sent: Monday, August 16, 1999 00:45
To: glasgow-haskell-users
Subject: (Stupid?) newbie question


Hi, folks!
 
I have recently downloaded ghc-4.03 (under win32/cygwin) and everything
seems to work great, but somehow the following code snippet does not
work as intended:
 
 
import System
 
main = do argv - getArg
   print argv
 
 
This does print "[]" - no arguments!
Since the same thing fails in Hugs too, I must have made some mistake.
 
please enlighted me.
 
 
thanks,
felix