I'm quite pleased with the readability of the following code. Let me take a shot at trying to explain how it works.
main = mapM_ (putStrLn . fizzbuzzer) [1..100] fizzbuzzer number | mod number 15 == 0 = "FizzBuzz" | mod number 3 == 0 = "Fizz" | mod number 5 == 0 = "Buzz" | otherwise = show number
I'm not too fond of the
mod number 15 part in there, but I'll explain why I think it can't be done without.
mapM_: Map each element of a structure to a monadic action, evaluate these actions from left to right, and ignore the results.
mapM would work here as well, except we don't care about the output anyway. Right?
A monadic action is required because I'm directly handling the I/O and all I/O is considered "impure" by Haskell. Everything impure should be wrapped in a Monad.
Basically, I iterate over every number in the range of 1 to 100 inclusive and put it in
fizzbuzzer. Depending on whether the number is a multiple of 3, 5, 15 or none of those, a
String is selected. This get's pushed into
putStrLn which outputs the
String. Because only one response can be selected, the output for being divisible by 15 has to be explicitly mentioned.
I think using pattern guards like I did here is idiomatic. It feels extensible, and that's a good thing for future Haskell solutions. Feel free to poke any holes in my code and/or theory.