[Haskell-beginners] Ord and Eq instances for complex types
Daniel Fischer
daniel.is.fischer at googlemail.com
Wed Oct 19 01:36:39 CEST 2011
On Wednesday 19 October 2011, 01:16:01, Mike Meyer wrote:
> On Tue, Oct 18, 2011 at 4:01 PM, Daniel Fischer <
>
> daniel.is.fischer at googlemail.com> wrote:
> > On Wednesday 19 October 2011, 00:27:19, Mike Meyer wrote:
> > > On Tue, Oct 18, 2011 at 2:47 PM, Daniel Fischer <
> > > I was actually contemplating adding a quality field to the record.
> >
> > If you don't export the constructors and take care to create only
> > hands with the correct quality, that is possible. I'm not sure if it
> > gains anything, though.
>
> That's pretty much what playing with it turned up.
>
> > > > 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.
> >
> > I don't see what you mean, could you elaborate?
>
> The hand types break down into three cases:
> ordered by the cards in the hand (HighCard, Straight, Flush,
> StraightFlush) ordered by a rank and then the cards (PairOf,
> ThreeOfAKind, FourOfAKind) ordered by two ranks and then the cards
> (TwoPair, FullHouse)
>
> I'd like to be able to match against the pattern ignoring the
> constructor, like so:
That's impossible, pattern matching is against (fully applied)
constructors.
>
> instance Order Hand where
> compare h1 h2 = case compare (quality h1) (quality h2) of
> EQ -> ex_compare h1 h2
> ne -> ne
> where ex_compare (_ c1) (_ c2) = compare c1 c2
> ex_compare (_ r1 c1) (_ r2 c2) = case compare r1 r2
> of ...
> ex_compare (_ r1 s1 c1) (_ r2 s2 c2) = case compare
> r1 r2 of ...
>
> Or something similar.
Guards?
ex_compare h1 h2
| plain h1 = compare (cards h1) (cards h2)
| oneRank h1 = compare (rank h1, cards h1) (rank h2, cards h2)
| otherwise = compare (rank h1, minorRank h1, cards h1)
(rank h2, minorRank h2, cards h2)
plain HighCard{} = True
plain StraightFlush{} = True
plain _ = False
oneRank FullHouse{} = False
oneRank h = not (plain h)
More information about the Beginners
mailing list