Vogel612 and I decided to take a shot at the StackSTV challenge in Haskell. This is part of the CRitter Collaboration challenge. Except I don't know any Haskell. So let's try a FizzBuzz first!
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[1]. 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.