4

谁能解释为什么下面的 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) ]

表达式应该有类型 Card 但这里有类型 'a * 'b

4

2 回答 2

10

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

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

您的意图是创建两个 type 值Card;您必须根据以下不同的联合案例提供适当的构造函数Card

let c1 = RankCard (Two, Diamonds)  // c1: Card
let c2 = FaceCard (Jack, Hearts) // c2: Card

现在您可以在同一个列表中使用c1and ,F# 类型检查器将自动推断具有的类型:c2deckdeckCard list

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

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

let deck = [RankCard (Two, Diamonds); FaceCard (Jack, Hearts)]
于 2012-02-06T14:32:36.180 回答
5

You need to use the RankCard or FaceCard constructor -- otherwise F# thinks you've just given it a normal list of tuples.

Alternatively, why not let F# infer the types itself?

于 2012-02-06T14:21:18.450 回答