Списки дискриминируемых союзов в fsharp

Кто-нибудь может объяснить, почему следующие 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, но здесь имеет тип 'список

а это пусть дает

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

ожидалось, что выражение будет иметь тип Card, но здесь имеет тип 'a * 'b

2 ответа

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 а также c2 в том же списке deckи F# тип проверки автоматически выведет deck иметь тип Card list:

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

Кроме того, у вас есть следующий список:

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

Вам нужно использовать RankCard или же FaceCard конструктор - иначе F# думает, что вы только что дали ему обычный список кортежей.

В качестве альтернативы, почему бы не позволить F# самому определять типы?

Другие вопросы по тегам