
On Tuesday 18 October 2011, 23:13:03, Mike Meyer wrote:
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.
Is there some third alternative I've overlooked that combines the best features of both approaches?
Thanks,
Well, you could use record syntax in the Hand type to avoid defining cards in the Eq instance, data Hand = HighCard { cards :: [Card] } | PairOf { rank :: Rank, cards :: [Card } ... | FulHouse { rank, minorRank :: Rank, cards :: [Card] } | FourOfAKind { rank :: Rank, cards :: [Card] } | StraightFlush { cards :: [Card] } deriving Show instance Eq Hand where -- if your hands are well-formed, you h1 == h2 = cards h1 == cards h2 -- could also derive Eq quality :: Hand -> Int quality HighCard{} = 0 quality PairOf{} = 1 ... quality StraightFlush{} = 8 instance Ord Hand where compare h1 h2 = case compare (quality h1) (quality h2) of EQ -> case h1 of StraightFlush c1 -> compare c1 (cards h2) FourOfAKind r1 c1 -> case compare r1 (rank h2) of EQ -> compare c1 (cards h2) other -> other ... other -> other