I am trying to represent standard playing cards in F#. My goal is to implement a clone of Microsoft Solitaire (the one that comes with Windows) , a game in which Cards' Suit, Face, and Color are important. This exercise is mostly intended as a way to learn some F#.
I have considered using discriminated unions:
type Suit =
| Diamonds
| Hearts
| Clubs
| Spades
type Color =
| Red
| Black
type Face =
Two | Three | Four | Five | Six | Seven |
Eight | Nine | Ten | Jack | Queen | King | Ace
with a record type for Card:
type Card = {
suit: Suit;
face: Face;
color: Color;
}
However, a Card's Color can be inferred from its Suit—all Diamonds and Hearts are Red, and all Clubs and Spades are Black. Suit cannot be determined from Color alone. Perhaps something like this is appropriate:
type Suit =
| Diamonds of Color //should always be red
| Hearts of Color //should always be red
| Clubs of Color //should always be black
| Spades of Color //should always be black
type Face =
Two | Three | Four | Five | Six | Seven |
Eight | Nine | Ten | Jack | Queen | King | Ace
type Card = {
suit: Suit;
face: Face;
}
But this doesn't seem right, since this allows incorrect combinations, e.g. Black Hearts and Red Spades.
My questions are:
- What is the most idiomatic way to handle Suit and Color, considering that Color is dependent on Suit?
- Should the concept of Color even be explicitly represented? One could theoretically just replace all occurrences of Color with pattern matches against Diamonds or Hearts (which are red) and Clubs or Spades (which are black).