List comprehensions are a very tidy syntax for this. If you derive Enum
on Rank
and Suit
you can express it very simply as:
pristineDeck = [ Card rank suit | suit <- [Hearts .. Clubs], rank <- [Ace .. King] ]
If you're wondering why I have suit
and rank
in different orders, the first is because of the order the Card
constructor uses, while the latter is to get the order of the resulting list--suits together in ascending order.
In more generality, or when a single list comprehension gets too bulky, the cartesian product is exactly the behavior given by the Monad
instance for lists. The following is equivalent to the list comprehension above:
pristineDeck = do suit <- [Hearts .. Clubs]
rank <- [Ace .. King]
return $ Card rank suit
As one other minor point, to save yourself the trouble of remembering what order the Suit
values are in, deriving Bounded
as well will enable to write [minBound .. maxBound]
to enumerate all values of any type with instances of both Enum
and Bounded
.