[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