[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