I have the following type definitions to represent cards:
data Suit = Hearts | Spades | Diamonds | Clubs
data Rank = Numeric Integer | Jack | Queen | King | Ace
data Card = Card Rank Suit
data Deck = None | Cons Card Deck
Numeric Integer represents ranks from 2 to 10.
Now I want to write a function to get the full deck:
fullDeck :: Deck
How could I generate the full deck in the most elegant way? I understand that some of these definitions are ugly but I have no freedom to choose this.
Thanks
Does something like
-- Not sure why you're reinventing a list but
fromList :: [Card] -> Deck
fromList = foldr Cons None
fullDeck = fromList [Card r s | s <- [Hearts, Spades, Diamonds, Clubs]
, r <- map Numeric [2..9]++[Jack, Queen, King, Ace]]
Look nice? we're just using list comprehensions to generate a list of all possibilities than smashing it into a Deck
.
You could consider using the universe package. It doesn't really make the code much easier, but it's fun. =)
Here's how it would look.
import Data.Universe
data Suit = Hearts | Spades | Diamonds | Clubs deriving (Bounded, Enum)
data Rank = Numeric Integer | Jack | Queen | King | Ace
instance Universe Suit
instance Universe Rank where
universe = map Numeric [2..10] ++ [Jack, Queen, King, Ace]
instance Finite Suit
instance Finite Rank
Now you can use universeF :: [(Rank, Suit)]
as your full deck of cards. If you really want custom Card
and Deck
types, you can add just a few lines of code:
data Card = Card Rank Suit
instance Universe Card where
universe = [Card rank suit | (rank, suit) <- universeF]
instance Finite Card
data Deck = None | Cons Card Deck
fullDeck = foldr Cons None universeF
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