[Haskell-beginners] Ord and Eq instances for complex types
Mike Meyer
mwm at mired.org
Tue Oct 18 23:13:03 CEST 2011
I'm working on a problem dealing with poker hands, and need to rank them.
The Ord instance seems like a natural for this, but the code came out with a
lot of repetitions in it. To wit, given suitable definitions for Rank, Suit
and Card, I define a Hand as:
data Hand = HighCard [Card]
| PairOf Rank [Card]
| TwoPair Rank Rank [Card]
| ThreeOfAKind Rank [Card]
| Straight [Card]
| Flush [Card]
| FullHouse Rank Rank [Card]
| FourOfAKind Rank [Card]
| StraightFlush [Card]
deriving (Show)
[N.B. - the single or double rank is the Rank of the cards participating in
that type of hand, and is compared before the rest of the cards, so AQQJT is
not as good a hand as KK321 - a pair of kings beating a pair of queens.]
Eq winds up looking like:
instance Eq Hand where
h1 == h2 = cards h1 == cards h2 where
cards (HighCard h) = h
cards (PairOf _ h) = h
-- etc.
and Ord (with appropriate check functions) like:
instance Ord Hand where
compare (StraightFlush h1) (StraightFlush h2) = compare h1 h2
compare (StraightFlush _) _ = GT
compare _ (StraightFlush _) = LT
compare (FourOfAKind r1 h1) (FourOfAKind r2 h2)= check r1 h1 r2 h2
compare (FourOfAKind _ _) _ = GT
compare _ (FourOfAKind _ _) = LT
-- etc
Seems like there ought to be an easier way. I can see that making the types
of hands an enum (HandType), then defining a hand as a record:
data Hand = {
type :: HandType,
rank1 :: Maybe Rank, -- (2, 3, 4) of a kind
rank2 :: Maybe Rank, -- 2 pair, full house
cards :: [Card]
}
would make the comparisons a lot easier. But that would make constructing
them a lot more painful. I can't just say "PairOf Ace hand" to mark a hand
as a pair of aces. It also the type checking from the constructors.
Is there some third alternative I've overlooked that combines the best
features of both approaches?
Thanks,
<mike
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20111018/f6971cde/attachment.htm>
More information about the Beginners
mailing list