我想在F#中代表标准扑克牌.我的目标是实现一个微软纸牌(Windows附带的一个)的克隆,一个卡片套装,面部和颜色很重要的游戏.这个练习主要是为了学习一些F#.
我考虑过使用歧视的工会:
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
Run Code Online (Sandbox Code Playgroud)
卡的记录类型:
type Card = {
suit: Suit;
face: Face;
color: Color;
}
Run Code Online (Sandbox Code Playgroud)
但是,卡片的颜色可以从它的套装中推断出来 - 所有钻石和红心都是红色的,所有的俱乐部和黑桃都是黑色的.不能仅从Color确定套装.也许这样的事情是合适的:
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;
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不对,因为这允许不正确的组合,例如Black Hearts和Red Spades.
我的问题是:
Mar*_*ann 16
既然Color总是可以推断出来Suit,那就没有理由明确地对它进行建模; 你想让非法国家无法代表.
您仍然可以从模型中获得良好的编程体验,并使用活动模式有一种很好的颜色建模方法:
type Suit =
| Diamonds
| Hearts
| Clubs
| Spades
let (|Red|Black|) suit =
match suit with
| Diamonds | Hearts -> Red
| Clubs | Spades -> Black
Run Code Online (Sandbox Code Playgroud)
这将使您能够模式匹配Suit,就像这个愚蠢的例子:
let printColor card =
match card.Suit with
| Red -> "Red"
| Black -> "Black"
Run Code Online (Sandbox Code Playgroud)
FSI的用法示例:
> printColor { Suit = Spades; Face = Ace };;
val it : string = "Black"
> printColor { Suit = Diamonds; Face = King };;
val it : string = "Red"
Run Code Online (Sandbox Code Playgroud)