On Tue, Oct 18, 2011 at 2:47 PM, Daniel Fischer < daniel.is.fischer@googlemail.com> wrote:
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
I was thinking of some kind of mixed solution over lunch. This looks better than what I had in mind. But what does "well-formed" mean in this context?
quality :: Hand -> Int quality HighCard{} = 0 quality PairOf{} = 1 ... quality StraightFlush{} = 8
Could this be replaced by an assoc list of some kind? I was actually contemplating adding a quality field to the record.
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
What I'd really like to do is collapse the three types of comparison (i.e. - hand, rank hand, rank minorrank hand) into one comparison each. Thanks, <mike