views:

308

answers:

1

I'm new to haskell, and i read through and digested Learn You A Haskell For Great Good, trying out a couple of things along the way. For my first project i wanted to try the classic: FizzBuzz. So i came up with the following code:

import System.IO

fizzBuzz :: (Integral a) => a -> String
fizzBuzz num
    | fizz && buzz = "FizzBuzz"
    | fizz = "Fizz"
    | buzz = "Buzz"
    | otherwise = show num
    where fizz = num `mod` 3 == 0
          buzz = num `mod` 5 == 0

main = print $ map fizzBuzz [1..100]

Worked great, except i got a rather dense looking list that was hard to read. So i tried this main function instead:

main = map putStrLn $ map fizzBuzz [1..100]

And that gives me the error Couldn't match expected type 'IO t' against inferred type '[IO ()]'. I tried half a dozen things and none of it seemed to help. What's the proper way to do what i'm trying to do?

+17  A: 
ephemient
Thank you, i knew haskell had something like that but i couldn't figure it out! now to understand *why* it works... :)
RCIX
As I tried to explain, you generated a list of `IO ()` actions, but you need to say *what* you want to do with them. `sequence` runs a list of monads in order, which happens to be what you want here. My last solution, instead, joins the fizz/buzz strings into a single multi-line string before it heads off into the strange land of `IO`.
ephemient
Yep, i just didn't make the connection between a monad and an IO action -- some of that tutorial is still a little fuzzy
RCIX