Skip to content

Instantly share code, notes, and snippets.

@bsima
Last active May 13, 2016 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsima/d14f996bd4700a17c7d4d8abfe135606 to your computer and use it in GitHub Desktop.
Save bsima/d14f996bd4700a17c7d4d8abfe135606 to your computer and use it in GitHub Desktop.
-- http://www.parsonsmatt.org/2016/02/27/an_elegant_fizzbuzz.html
import Data.Foldable
import Data.Maybe
type FizzRule = Integer -> Maybe String
rule :: Integer -> String -> FizzRule
rule n m i =
case i `mod` n of
0 -> Just m
_ -> Nothing
fizz = rule 3 "Fizz"
buzz = rule 5 "Buzz"
fizzBuzz :: (Functor f, Foldable t)
=> t (Integer -> Maybe String)
-> f Integer
-> f String
fizzBuzz rules = fmap (fromMaybe <$> show <*> ruleSet)
where
ruleSet = fold rules
{- example repl session
λ> :l fizzbuzz.hs
[1 of 1] Compiling Main ( fizzbuzz.hs, interpreted )
Ok, modules loaded: Main.
λ> fizzBuzz [fizz, buzz]
fizzBuzz [fizz, buzz] :: Functor f => f Integer -> f String
?? now what do ??
-}
@tfausak
Copy link

tfausak commented May 13, 2016

You have to wrap the Integer argument in a Functor, specifically a list.

fizzBuzz [fizz, buzz] [10 .. 15]
-- ["Buzz","11","Fizz","13","14","FizzBuzz"]

To get the output you might expect, you can map over the output strings and print them.

mapM_ putStrLn (fizzBuzz [fizz, buzz] [10 .. 15])
-- Buzz
-- 11
-- Fizz
-- 13
-- 14
-- FizzBuzz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment