{-# OPTIONS -fno-warn-missing-methods #-}
module Cards where
import Test.QuickCheck
import System.Random
-- A card has a rank and belongs to a suit.
data Card = Card { rank :: Rank, suit :: Suit }
deriving (Eq, Show)
instance Arbitrary Card where
arbitrary = do
suit <- arbitrary
rank <- arbitrary
return (Card rank suit)
-- All the different suits.
data Suit = Hearts | Spades | Diamonds | Clubs
deriving (Eq, Show)
instance Arbitrary Suit where
arbitrary = oneof [ return Hearts, return Spades
, return Diamonds, return Clubs ]
-- A rank is either a numeric card, a face card, or an ace. The
-- numeric cards range from two to ten.
data Rank = Numeric Integer | Jack | Queen | King | Ace
deriving (Eq, Show)
instance Arbitrary Rank where
arbitrary = frequency [ (1, return Jack)
, (1, return Queen)
, (1, return King)
, (1, return Ace)
, (9, do n <- choose (2, 10)
return (Numeric n))
]
-- A hand of cards. This data type can also be used to represent a
-- deck of cards.
data Hand = Empty | Add Card Hand
deriving (Eq, Show)
-- This instance on average yields larger hands than the one given in
-- the lecture.
instance Arbitrary Hand where
arbitrary = frequency [ (1, return Empty)
, (10, do card <- arbitrary
hand <- arbitrary
return (Add card hand))
]
-- The size of a hand.
size :: Num a => Hand -> a
size Empty = 0
size (Add card hand) = 1 + size hand
-- We also need to be able to generate random number generators. (This
-- does not really belong in this file, but is placed here to reduce
-- the number of files needed.)
instance Arbitrary StdGen where
arbitrary = do n <- arbitrary
return (mkStdGen n)