Reputation: 11595
Is there a simpler way to initialize this deck of cards using F#?
let create() = [ 0..12 ]
type Suit =
| Spades of list<int>
| Hearts of list<int>
| Clubs of list<int>
| Diamonds of list<int>
let spades = create() |> Spades
let hearts = create() |> Hearts
let clubs = create() |> Clubs
let diamonds = create() |> Diamonds
Specifically, I would like to simplify the initialization of these four suits. Is there a simpler way to do this?
Could I enumerate the types of on this discriminated union and assign it to some "deck" structure?
NOTE:
I am new to F#. So please forgive me if this question seems ignorant.
Upvotes: 1
Views: 338
Reputation: 233125
I don't think that there's a more succinct way, but I also wouldn't model playing cards like this, because it doesn't help making illegal states unrepresentable. As an example, I can do this:
> Spades [-1; 10; 100];;
val it : Suit = Spades [-1; 10; 100]
What does that even mean?
Instead, I'd probably model cards like this:
type Suit = Diamonds | Hearts | Clubs | Spades
type Face =
| Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten
| Jack | Queen | King | Ace
type Card = { Suit: Suit; Face: Face }
This would enable you to express any valid card:
> { Suit = Spades; Face = Ace };;
val it : Card = {Suit = Spades;
Face = Ace;}
On the other hand, you can't express invalid
cards:
> { Suit = Spades; Face = Hundred };;
{ Suit = Spades; Face = Hundred };;
------------------------^^^^^^^
stdin(4,25): error FS0039: The value or constructor 'Hundred' is not defined
Initialisation looks, in this model, a bit cumbersome, but on the other hand, the following deck
is an immutable value, so once it's defined, you can reuse the deck again and again.
let deck = [
{ Suit = Diamonds; Face = Two };
{ Suit = Diamonds; Face = Three };
{ Suit = Diamonds; Face = Four };
{ Suit = Diamonds; Face = Five };
{ Suit = Diamonds; Face = Six };
{ Suit = Diamonds; Face = Seven };
{ Suit = Diamonds; Face = Eight };
{ Suit = Diamonds; Face = Nine };
{ Suit = Diamonds; Face = Ten };
{ Suit = Diamonds; Face = Jack };
{ Suit = Diamonds; Face = Queen };
{ Suit = Diamonds; Face = King };
{ Suit = Diamonds; Face = Ace };
{ Suit = Hearts; Face = Two };
{ Suit = Hearts; Face = Three };
{ Suit = Hearts; Face = Four };
{ Suit = Hearts; Face = Five };
{ Suit = Hearts; Face = Six };
{ Suit = Hearts; Face = Seven };
{ Suit = Hearts; Face = Eight };
{ Suit = Hearts; Face = Nine };
{ Suit = Hearts; Face = Ten };
{ Suit = Hearts; Face = Jack };
{ Suit = Hearts; Face = Queen };
{ Suit = Hearts; Face = King };
{ Suit = Hearts; Face = Ace };
{ Suit = Clubs; Face = Two };
{ Suit = Clubs; Face = Three };
{ Suit = Clubs; Face = Four };
{ Suit = Clubs; Face = Five };
{ Suit = Clubs; Face = Six };
{ Suit = Clubs; Face = Seven };
{ Suit = Clubs; Face = Eight };
{ Suit = Clubs; Face = Nine };
{ Suit = Clubs; Face = Ten };
{ Suit = Clubs; Face = Jack };
{ Suit = Clubs; Face = Queen };
{ Suit = Clubs; Face = King };
{ Suit = Clubs; Face = Ace };
{ Suit = Spades; Face = Two };
{ Suit = Spades; Face = Three };
{ Suit = Spades; Face = Four };
{ Suit = Spades; Face = Five };
{ Suit = Spades; Face = Six };
{ Suit = Spades; Face = Seven };
{ Suit = Spades; Face = Eight };
{ Suit = Spades; Face = Nine };
{ Suit = Spades; Face = Ten };
{ Suit = Spades; Face = Jack };
{ Suit = Spades; Face = Queen };
{ Suit = Spades; Face = King };
{ Suit = Spades; Face = Ace }; ]
Although this looks tedious, you only have to write this once. Since deck
is a value, you can make it a value that belongs to a module. Clients can simply use this value, instead of having to initialise a deck by themselves.
Upvotes: 5