Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bowling kata in Haskell.
import Test.Hspec
score :: [Int] -> Int
score rolls = score' 10 rolls
where
score' 0 rolls = 0
score' framesLeft rolls =
let (frameScore, restRolls) = popFrame rolls
in frameScore + score' (framesLeft - 1) restRolls
popFrame :: [Int] -> (Int, [Int])
popFrame rolls
| isStrike rolls = (sum (take 3 rolls), drop 1 rolls)
| isSpare rolls = (sum (take 3 rolls), drop 2 rolls)
| otherwise = (sum (take 2 rolls), drop 2 rolls)
isStrike rolls = sum (take 1 rolls) == 10
isSpare rolls = sum (take 2 rolls) == 10
main = hspec $ do
describe "bowling score" $ do
describe "is sum of pins if no spare or strike" $ do
it "no pins knocked down" $ do
(0 `rollTimes` 20) `shouldGiveScore` 0
it "one pin knocked down in each throw" $ do
(1 `rollTimes` 20) `shouldGiveScore` 20
describe "spare gives bonus for next throw" $ do
it "at beginning" $ do
([4, 6, 3, 0] ++ (0 `rollTimes` 16))
`shouldGiveScore` (((4 + 6) + 3) + (3 + 0) + 0)
it "in the middle" $ do
((0 `rollTimes` 10) ++ [4, 6, 3, 0] ++ (0 `rollTimes` 6))
`shouldGiveScore` (0 + ((4 + 6) + 3) + (3 + 0) + 0)
it "at the end" $ do
((0 `rollTimes` 18) ++ [4, 6, 3])
`shouldGiveScore` (0 + ((4 + 6) + 3))
describe "strike gives bonus for next two throws" $ do
it "at beginning" $ do
([10, 3, 4] ++ (0 `rollTimes` 16))
`shouldGiveScore` ((10 + 3 + 4) + (3 + 4) + 0)
it "all strikes (golden game)" $ do
(10 `rollTimes` 12) `shouldGiveScore` 300
rollTimes :: a -> Int -> [a]
rollTimes value n = replicate n value
shouldGiveScore :: [Int] -> Int -> Expectation
shouldGiveScore rolls expectedScore = score rolls `shouldBe` expectedScore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.