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, <mike
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