我想在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
卡的记录类型:
type Card = {
    suit: Suit;
    face: Face;
    color: Color;
}
但是,卡片的颜色可以从它的套装中推断出来 - 所有钻石和红心都是红色的,所有的俱乐部和黑桃都是黑色的.不能仅从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;
}
但这似乎不对,因为这允许不正确的组合,例如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
这将使您能够模式匹配Suit,就像这个愚蠢的例子:
let printColor card =
    match card.Suit with
    | Red -> "Red"
    | Black -> "Black"
FSI的用法示例:
> printColor { Suit = Spades; Face = Ace };;
val it : string = "Black"
> printColor { Suit = Diamonds; Face = King };;
val it : string = "Red"