Types + Properties = Software: initial state by Mark Seemann
How to define the initial state in a tennis game, using F#.
This article is the sixth in a series of articles that demonstrate how to develop software using types and properties. In the previous article, you saw how to compose a function that returns a new score based on a previous score, and information about which player won the ball. In this article, you'll see how to define the initial state of a tennis game.
The source code for this article series is available on GitHub.
Initial state #
You may recall from the article on designing with types that a Score is a discriminated union. One of the union cases is the Points case, which you can use to model the case where both players have either Love, Fifteen, or Thirty points.
The game starts with both players at love. You can define this as a value:
let newGame = Points { PlayerOnePoint = Love; PlayerTwoPoint = Love }
Since this is a value (that is: not a function), it would make no sense to attempt to test it. Thus, you can simply add it, and move on.
You can use this value to calculate ad-hoc scores from the beginning of a game, like this:
> let firstBall = score newGame PlayerTwo;; val firstBall : Score = Points {PlayerOnePoint = Love; PlayerTwoPoint = Fifteen;} > let secondBall = score firstBall PlayerOne;; val secondBall : Score = Points {PlayerOnePoint = Fifteen; PlayerTwoPoint = Fifteen;}
You'll soon get tired of defining firstBall
, secondBall
, thirdBall
, and so on, so a more general way to handle and calculate scores is warranted.
To be continued... #
In this article, you saw how to define the initial state for a tennis game. There's nothing to it, but armed with this value, you now have half of the requirements needed to turn the tennis score function into a finite state machine. You'll see how to do that in the next article.