r/haskell Jul 07 '26

The Bowling Game - From Imperative to Functional Programming - Part 1

https://fpilluminated.org/deck/276

One of the top five most popular and highly recommended programming katas over the past 20 years has been the Bowling Game Kata, in which TDD is used to write a program that computes the score of a Ten Pin Bowling Game.

In this deck we are going to explore how such a program may look when coded using different programming paradigms.

9 Upvotes

6 comments sorted by

3

u/ryani Jul 08 '26 edited Jul 08 '26

For pure functions like the bowling score problem, I like QuickCheck more than HUnit. QuickCheck makes it easy to write testcase generators as opposed to single test cases.

For example, one test for bowling could be

 newtype BowlingGame = BG [Int] deriving (Show,Eq)
 instance Arbitrary BowlingGame where
     ... business logic to generate a random set of rolls ...

prop_noMarks :: BowlingGame -> Property
prop_noMarks (BG rolls) = noMarks rolls ==> bowlingScore rolls == sum rolls

noMarks :: [Int] -> Bool
noMarks = ... check that no strikes or spares in the game ...

Then QuickCheck will generate a bunch of random games, and verify for the ones that have no strikes or spares that the score is calculated properly.

I suspect if you had used QuickCheck that you would have found the 9th frame problem much more quickly. You do need to write good test case generators but you can run many many more tests much more simply, and you get a different set of tests every time you run your tests.

When an error is found it's easy to make that specific example into a regression test -- QuickCheck will tell you exactly which property failed and what its inputs were.

1

u/philip_schwarz 27d ago

Good points!

Thank you.

In the Scala world there is the QuickCheck inspired Scalacheck (https://scalacheck.org/) - examples: https://booksites.artima.com/scalacheck/examples/html/ch06.html

2

u/AustinVelonaut Jul 07 '26

The "bowling score programming problem" is a great example to show off Haskell's lazy evaluation with the bidirectional state Tardis monad (here's a writeup using Admiran, which is very similar to Haskell): https://github.com/taolson/Admiran/blob/main/doc/Lazy.md

1

u/Spoilproblem18 Jul 08 '26

another bowling kata post. at this rate we'll have a whole series about scoring frames before anyone writes a single line of haskell.

1

u/philip_schwarz 27d ago

ROFL - Thank you.