I am learning Haskell, so I’m writing some simple card games. I’ve defined some data types:
data Rank = Ace|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Jack|Queen|King deriving (Eq,Show,Ord)
data Suit = Hearts|Spades|Diamonds|Clubs deriving (Show)
data Card = Card Rank Suit
Now I’d like to create a pristine deck of 52 cards. I’m sure there is a slick way to do it, but all I can come up with is:
pristineDeck = [Card Ace Hearts, Card Two Hearts, ...]
Can I get Haskell to generate this list for me?
List comprehensions are a very tidy syntax for this. If you derive
EnumonRankandSuityou can express it very simply as:If you’re wondering why I have
suitandrankin different orders, the first is because of the order theCardconstructor 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
Monadinstance for lists. The following is equivalent to the list comprehension above:As one other minor point, to save yourself the trouble of remembering what order the
Suitvalues are in, derivingBoundedas well will enable to write[minBound .. maxBound]to enumerate all values of any type with instances of bothEnumandBounded.