Skip to content

Instantly share code, notes, and snippets.

@serafo27
Last active July 18, 2019 19:48
Show Gist options
  • Save serafo27/b95f4353ec38865d9b46392e336f99b7 to your computer and use it in GitHub Desktop.
Save serafo27/b95f4353ec38865d9b46392e336f99b7 to your computer and use it in GitHub Desktop.
FIzz Buzz kata in haskell
module FizzBuzz where
import Data.Maybe
import Data.List
import Data.Char (digitToInt)
type Rule = Int -> Maybe String
fizz = oR (word 3 "fizz") (contains 3 "fizz")
buzz = word 5 "buzz"
ticino = word 7 "ticino"
rules = [fizz, buzz, ticino]
oR :: Rule -> Rule -> Rule
oR x y = \n -> combineK [x, y] n
where combineK [] _ = Nothing
combineK (r:rs) n = if isJust (r n) then (r n) else combineK rs n
word :: Int -> String -> Rule
word d w = \n -> if n `mod` d == 0 then Just w else Nothing
contains :: Int -> String -> Rule
contains d w = \n -> if d `elem` (toDigits n) then Just w else Nothing
where toDigits = map digitToInt . show
render :: Int -> String
render n = getOrElse folDMap n
folDMap :: Int -> Maybe String
folDMap x = if concats == "" then Nothing else Just concats
where concats = foldMap (maybe "" id) (ruleResults x)
ruleResults = (\x -> map (\f -> f x) rules)
getOrElse :: Rule -> Int -> String
getOrElse f x = if isJust (f x) then fromJust (f x) else show x
start = map render [1..49]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment