F # simulation of playing cards

I am trying to introduce standard playing cards in F #. My goal is to implement the Microsoft Solitaire clone (the one that comes with Windows), a game in which Costume, Face and Color are important. This exercise is mainly designed to learn some F #.

I reviewed the use of discriminated associations:

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 record type for Card:

 type Card = { suit: Suit; face: Face; color: Color; } 

However, the color of the card can be inferred from his suit: all diamonds and hearts are red, and all clubs and spades are black. Costume cannot be determined only by color. Maybe something like this fits:

 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 does not seem right, as it allows for the wrong combinations, for example. Black hearts and red peaks.

My questions:

  • What is the most idiomatic way to process a suit and color, given that color depends on the suit?
  • Should the concept of color even be explicitly presented? Theoretically, one could simply replace all occurrences of color with matching patterns with diamonds or hearts (red) and clubs or spades (which are black).
+5
source share
2 answers

Since Color can always be inferred from Suit , there is no reason to explicitly model it; you want to make illegal states unpredictable .

You can still get good programming experience from your model and have a good way of modeling colors using the Active template :

 type Suit = | Diamonds | Hearts | Clubs | Spades let (|Red|Black|) suit = match suit with | Diamonds | Hearts -> Red | Clubs | Spades -> Black 

This will allow you to map the pattern by Suit , like this example:

 let printColor card = match card.Suit with | Red -> "Red" | Black -> "Black" 

Example usage from FSI:

 > printColor { Suit = Spades; Face = Ace };; val it : string = "Black" > printColor { Suit = Diamonds; Face = King };; val it : string = "Red" 
+14
source

You can add a recording method:

 type Card = {suit: Suit;face: Face} member this.Color = match this.suit with | Diamonds | Hearts -> Red | Clubs | Spades -> Black 

Example:

 let v = {suit = Diamonds;face = Two} printfn "%A" v.Color let v1 = {suit = Clubs;face = Two} printfn "%A" v1.Color 

Red black. To continue, press any button.,.

+3
source

Source: https://habr.com/ru/post/1215202/


All Articles