# Yet another FizzBuzz in Haskell

Time for the most original question of the year: writing a FizzBuzz in Haskell!

So here is what I came up with:

fizzBuzz :: [Int] -> [String]
fizzBuzz xs =
[fizz x | x <- xs]

fizz :: Int -> String
fizz x
| mod x 15 == 0  = "FizzBuzz"
| mod x 3 == 0   = "Fizz"
| mod x 5 == 0   = "Buzz"
| otherwise      = show x


Then I can call

> mapM_ print $fizzBuzz [1..15] "1" "2" "Fizz" "4" "Buzz" etc  My questions are: • What are obvious awkwardnesses in this code? • How could I mix fizzBuzz and fizz so that there's only one function? • In fizz, is it possible to use a string buffer so that I get rid of the mod x 15 == 0 guard, taking advantage of its redundancy with mod 3 x == 0 and mod 5 x == 0? • Did you take a look at other fizzbuzzhaskell questions, like this one? – Mast Nov 30 '16 at 14:49 • @Mast I didn't check this particular one - great answers indeed – Jivan Nov 30 '16 at 14:55 • "string buffer" isn't really a thing in Haskell. After all, all values are immutable. You're probably thinking of str = n % 3 ? "Fizz" : ""; str += n % 5 ? "Buzz" : ""; return str == "" ? n.toString() : str;. But you cannot mutate str in Haskell. – Zeta Nov 30 '16 at 16:38 • The equivalent of (n % 3 ? "Fizz" : "") + (n % 5 ? "Buzz" : "") would work, but you wouldn't get the "otherwise show x" part for free. – Gurkenglas Nov 30 '16 at 20:32 • @Gurkenglas: Sure, but at that point you're using a binding either way. It's not like you'll type (if rem n 3 == 0 then "Fizz" else "") ++ (if rem n 5 == 0 then "Buzz" else "") twice, so there is a where str = ... (hopefully). An Alternative instance that doesn't concatenate the lists would make that a real one-liner, though. Or a small helper orElse :: [a] -> [a] -> [a]; orElse [] ys = ys; orElse xs _ = xs. But then were merely moving lines. – Zeta Nov 30 '16 at 21:16 ## 2 Answers [fizz x | x <- xs] is the same as map fizz xs, so fizzBuzz = map fizz. You can use putStrLn instead of print to print strings without quotes. Using the fact that map (g . f) = map g . map f, you can merge mapM_ putStrLn and map fizz into: mapM_ (putStrLn . fizz) [1..15]  Another solution with everything in single function and without mod x 15: import Control.Monad (forM_, when) fizzBuzz :: IO () fizzBuzz = forM_ [1..15]$ \x -> do
let [m3, m5] = map ((==0) . mod x) [3,5]
when m3 $putStr "Fizz" when m5$ putStr "Buzz"
when (not m3 && not m5) $putStr$ show x
putStrLn ""


I feel like your solution is overly complex, recursion can make this operation simpler:

fizzBuzz :: (Integral a) => [a] -> [String]
fizzBuzz [] = []
fizzBuzz (x : xs)
| x mod 15 == 0        = "FizzBuzz" : fizzBuzz xs
| x mod 3 == 0         = "Fizz" : fizzBuzz xs
| x mod 5 == 0         = "Buzz" : fizzBuzz xs
| otherwise              = fizzBuzz xs

main = do
print \$ fizzBuzz [1..20]


Using two functions to perform this is overkill. Using (Integral a) => in the type signature allows you to apply this function to float's, int's etc