
Here's a code fragment I have from working with Hal Daume's "Yet Another Haskell Tutorial". I cannot figure out how to iterate over the result from askForNumbers that returns "IO [Integer]", and print them. The "<-" operator seems to take IO off of the results from actions like getContents, which returns type "IO String", but I cannot seem to use it to take IO off of lists with it. What am I supposed to do? Also, as a side question, what should I be returning from the do function?
code>>>>
module Main
where
import IO
main = do
hSetBuffering stdin LineBuffering
s <- askForNumbers {-- This compiles --}
map show s {-- But this doesn't. Why? --}
{-- What expression should I be returning from
do? --}
askForNumbers = do
putStrLn "Give me a number (or 0 to stop):"
guess <- getLine
let number = read guess
if number == 0
then return []
else do
rest <- askForNumbers
return (number : rest)
<<

On 6/20/06, Taro Ikai
Here's a code fragment I have from working with Hal Daume's "Yet Another Haskell Tutorial". I cannot figure out how to iterate over the result from askForNumbers that returns "IO [Integer]", and print them.
The "<-" operator seems to take IO off of the results from actions like getContents, which returns type "IO String", but I cannot seem to use it to take IO off of lists with it. What am I supposed to do?
Also, as a side question, what should I be returning from the do function?
code>>>>
module Main where
import IO
main = do hSetBuffering stdin LineBuffering s <- askForNumbers {-- This compiles --} map show s {-- But this doesn't. Why? --}
s is a list of numbers, "map show s" is a list of Strings. It is not an IO [Strings] so you can't use it like an action. Think about what you're trying to do here, you map "show" on a list of ints, but what do you do with the result? Nothing. Why would you *want* the above to compile? It would just convert a bunch of numbers into strings and then forget about them! So what you want is probably something like: let xs = map show s The rule of thumb is, "use 'let' for regular values, and (<-) for actions". If you want to print all of them you could do something like: printList [] = return () printList (x:xs) = do putStrLn x printList xs On the other hand, this operation seems generally useful, so why not generalise it a bit? mapAction [] = return () mapAction a (x:xs) = do a x mapAction a xs And in fact, this function already exists! It's called mapM_ (the M is for Monad). You could use this by passing in "putStrLn" as the action to this function. /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

Sebastian, Thanks for your help. I learned two things: o show is not an action, but a function. Using it in the interactive mode of GHCI was making me confused. o To output anything, I need to do 'do'. -Taro Sebastian Sylvan wrote:
On 6/20/06, Taro Ikai
wrote: Here's a code fragment I have from working with Hal Daume's "Yet Another Haskell Tutorial". I cannot figure out how to iterate over the result from askForNumbers that returns "IO [Integer]", and print them.
The "<-" operator seems to take IO off of the results from actions like getContents, which returns type "IO String", but I cannot seem to use it to take IO off of lists with it. What am I supposed to do?
Also, as a side question, what should I be returning from the do function?
code>>>>
module Main where
import IO
main = do hSetBuffering stdin LineBuffering s <- askForNumbers {-- This compiles --} map show s {-- But this doesn't. Why? --}
s is a list of numbers, "map show s" is a list of Strings. It is not an IO [Strings] so you can't use it like an action. Think about what you're trying to do here, you map "show" on a list of ints, but what do you do with the result? Nothing. Why would you *want* the above to compile? It would just convert a bunch of numbers into strings and then forget about them! So what you want is probably something like:
let xs = map show s
The rule of thumb is, "use 'let' for regular values, and (<-) for actions".
If you want to print all of them you could do something like:
printList [] = return () printList (x:xs) = do putStrLn x printList xs
On the other hand, this operation seems generally useful, so why not generalise it a bit?
mapAction [] = return () mapAction a (x:xs) = do a x mapAction a xs
And in fact, this function already exists! It's called mapM_ (the M is for Monad). You could use this by passing in "putStrLn" as the action to this function.
/S

o To output anything, I need to do 'do'.
If you only have one action, you can omit do, e.g. main = do { putStrLn "Hello, World!" } is identical (after de-sguaring) to main = putStrLn "Hello, World!" Essentially, you are correct; to output anything (i.e. to perform I/O by side effect) your actions will be inside the I/O monad, typically inside of a 'do' block. Jared. -- http://www.updike.org/~jared/ reverse ")-:"

Hello Taro, Tuesday, June 20, 2006, 9:32:51 AM, you wrote:
o To output anything, I need to do 'do'.
no, you should perform something having "IO ..." return type. "do" is just a syntax way to join several "IO ..." actions into one action having this type. i plan to write "i/o and monads for beginners" introductory text, because your questions is very typical for this list -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

2006/6/20, Taro Ikai
Sebastian,
Thanks for your help. I learned two things:
o show is not an action, but a function. Using it in the interactive mode of GHCI was making me confused.
hi, in ghci, if I want to see the result of an IO action, I do this ghci> x <- myIOAction ghci> x I dont know if it s the right way but it works.. mt
participants (5)
-
Bulat Ziganshin
-
Jared Updike
-
minh thu
-
Sebastian Sylvan
-
Taro Ikai