fsharp中受歧视的工会名单

时间:2012-02-06 14:17:59

标签: f# discriminated-union

任何人都可以解释为什么以下2个let语句不起作用?

 type Rank =
 | Two
 | Three
 | Four
 | Five
 | Six
 | Seven
 | Eight
 | Nine
 | Ten

 type Face =
 | Jack
 | Queen
 | King
 | Ace

 type Suit =
 | Diamonds
 | Clubs
 | Hearts
 | Spades

 type Card =
 | RankCard of Rank * Suit
 | FaceCard of Face * Suit


 let deck : Card = [ (Two, Diamonds); (Jack, Hearts) ]

这个表达式应该有Card类型,但这里有类型'a list

这个让我们给出

 let deck : Card list = [ (Two, Diamonds); (Jack, Hearts) ]

表达式预计有类型卡,但这里有类型'a *'b

2 个答案:

答案 0 :(得分:10)

F#是一种类型安全的语言。因此,第一个表达式是错误的,因为Card'a list不兼容。第二个表达式也不正确,因为您的注释需要Card类型中的列表元素,但您提供了元组。

此外,(Two, Diamonds)(Jack, Hearts)在同一个列表中使用甚至不合法。前者是Rank * Suit的元组,后者是Face * Suit的元组。

您打算创建两个Card类型的值;您必须根据Card

的不同联合案例提供适当的构造函数
let c1 = RankCard (Two, Diamonds)  // c1: Card
let c2 = FaceCard (Jack, Hearts) // c2: Card

现在,您可以在同一列表c1中使用c2deck,而F#类型检查器会自动推断deck的类型为Card list

let deck = [c1; c2] // deck: Card list

或者,您有一个如下列表:

let deck = [RankCard (Two, Diamonds); FaceCard (Jack, Hearts)]

答案 1 :(得分:4)

您需要使用RankCardFaceCard构造函数 - 否则F#认为您只是给它一个正常的元组列表。

或者,为什么不让F#推断出类型呢?