F#模式匹配嵌套的判别联盟

dlk*_*kmp 4 f# pattern-matching

我有一个嵌套的歧视联盟代表一副扑克牌:

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

type Card =
| Heart of Symbol
| Diamond of Symbol
| Spade of Symbol
| Club of Symbol
Run Code Online (Sandbox Code Playgroud)

现在我想写一个函数返回给定卡的值,在我的情况下,它独立于卡片套装:

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

这写起来显然很乏味.有没有办法做这样的事情

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

非常感谢.

Fyo*_*kin 9

您错误地建模了数据.由于总甲板是套装和等级的完整笛卡尔积,因此将"包裹"等级划分为西装是没有意义的.这两者应该是卡片的独立,同等重要的属性:

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
   ...
Run Code Online (Sandbox Code Playgroud)

  • @dlkmp - 这是正确的答案.Chad Gilbert的答案有效,但只要你的数据模型不正确,你就会遇到更多这样的问题.正确地获取您的数据模型,其余代码将更自然地流动. (4认同)

Cha*_*ert 6

您将无法以这种方式绕过构造函数匹配,但您可以通过创建一个从卡中拉出符号的函数来删除一些单调乏味:

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
  ...
Run Code Online (Sandbox Code Playgroud)