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 ??
-}
@bsima
Copy link
Author

bsima commented May 2, 2016

λ> let f = fizzBuzz [fizz, buzz]
λ> :t f
f :: Functor f => f Integer -> f String
λ> f 10

<interactive>:32:1-4:
    No instance for (Functor f0) arising from a use of it
    The type variable f0 is ambiguous
    Note: there are several potential instances:
      instance Functor (Either a) -- Defined in ‘Data.Either’
      instance Functor Data.Proxy.Proxy -- Defined in ‘Data.Proxy’
      instance GHC.Arr.Ix i => Functor (GHC.Arr.Array i)
        -- Defined in ‘GHC.Arr’
      ...plus six others
    In the first argument of print, namely it
    In a stmt of an interactive GHCi command: print it
λ> 

I think fizzBuzz returns a function that actually calculates the Fizz Buzz algorithm, but I can't figure out how to use it yet...

@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