F # Pattern matching nested discriminated unions

I have a nested discriminatory union representing a deck of playing cards:

type Symbol =
| Seven
| Eight
| Nine
| Ten
| Jack
| Queen
| King
| Ace

type Card =
| Heart of Symbol
| Diamond of Symbol
| Spade of Symbol
| Club of Symbol

Now I want to write a function that returns the value of this card, which in my case does not depend on the card suit:

let GetValue (card : Card) =
  match card with
  | Heart(Seven) -> 0
  | Diamond(Seven) -> 0
  | Spade(Seven) -> 0
  | Club(Seven) -> 0
  ...

It is obviously tiring to write. Is there a way to do something like this

let GetValue (card : Card) =
  match card with
  | _(Seven) | _(Eight) | _(Nine) -> 0
  | _(Ten) -> 10
 ...

Many thanks.

+4
source share
3 answers

You won’t be able to get around the design match this way, but you can remove some of the boredom by creating a function to pull a character from the map:

let symbol card =
  match card with
  | Heart(s) -> s
  | Diamond(s) -> s
  | Spade(s) -> s
  | Club(s) -> s

let GetValue (card : Card) =
  match symbol card with
  | Seven | Eight | Nine -> 0
  | Ten -> 10
  ...
+5
source

. , "" . , :

type Symbol =
  | Seven
  | Eight
  | Nine
  | Ten
  | Jack
  | Queen
  | King
  | Ace

type Suit =
  | Heart
  | Diamond
  | Spade
  | Club

type Card = { suit: Suit; rank: Rank }

let getValue (card:Card) = 
   match card.rank with
   | Seven | Eight | Nine -> 0
   | Ten -> 10
   ...
+9

Here is another way:

let set789 = [Seven; Eight; Nine] |> Set.ofList
let cardValue x =
    match x with
    | y when Set.contains y set789 -> 0
    | Ten   ->  1
    | Jack  ->  2
    | Queen ->  3
    | King  ->  4
    | Ace   ->  5
    | _     -> -1

let GetValue (card : Card) =
  match card with
  | Club(x) | Spade(x) | Diamond(x) | Heart(x) -> cardValue x
+1
source

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


All Articles