I've a nested discriminated 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 returning the value of a given card which in my case is independent of the cards suit:
let GetValue (card : Card) =
match card with
| Heart(Seven) -> 0
| Diamond(Seven) -> 0
| Spade(Seven) -> 0
| Club(Seven) -> 0
...
This is obviously tedious to write. Is there a way to do something like this
let GetValue (card : Card) =
match card with
| _(Seven) | _(Eight) | _(Nine) -> 0
| _(Ten) -> 10
...
Thanks a lot.
You're modeling your data incorrectly. Since the total deck is the full Cartesian product of suits and ranks, it doesn't make sense to "wrap" ranks in suits. The two should be independent, equally important attributes of a card:
type Rank =
| 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
...
You won't be able to bypass constructor matching in that fashion, but you can remove some tedium by creating a function to pull the symbol out of a card:
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
...
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With