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