HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Yet another FizzBuzz in Haskell

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
yetanotherhaskellfizzbuzz

Problem

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  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?

Solution

[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 ""

Code Snippets

mapM_ (putStrLn . fizz) [1..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 ""

Context

StackExchange Code Review Q#148560, answer score: 3

Revisions (0)

No revisions yet.