Can anybody explain why following 2 let statements don't work?
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) ]
This expression was expected to have type Card but here has type 'a list
and this let gives
let deck : Card list = [ (Two, Diamonds); (Jack, Hearts) ]
expression was expected to have type Card but here has type 'a * 'b
F# is a type-safe language. So the first expression is wrong since Card and 'a list are incompatible. The second expression is also incorrect because your annotation requires list elements in Card type but you provided tuples instead.
Moreover, (Two, Diamonds) and (Jack, Hearts) are not even legal to use in the same list. The former is a tuple of Rank * Suit and the latter is a tuple of Face * Suit.
Your intention is creating two values of type Card; you have to provide appropriate constructors based on different union cases of Card:
let c1 = RankCard (Two, Diamonds) // c1: Card
let c2 = FaceCard (Jack, Hearts) // c2: Card
Now you can use c1 and c2 in the same list deck, and F# type checker will automatically infer deck to have the type of Card list:
let deck = [c1; c2] // deck: Card list
Alternatively, you have a list as follows:
let deck = [RankCard (Two, Diamonds); FaceCard (Jack, Hearts)]
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With