Списки дискриминируемых союзов в 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# самому определять типы?