Singular Type Constructor

Levent Erkok erkok@cse.ogi.edu
Sun, 12 Aug 2001 18:26:16 +0000


> So say you wanted to define a sort of "equality" on pairs (this isn't
> made up -- I wanted to do just this, recently).  Say you have:
>
> data MyPair a b = MyPair a b
>
> instance (Eq a, Eq b) => Eq (MyPair a b) where
>     (MyPair a b) == (MyPair a' b') = (a == a') && (b == b')
>
> this is obvious.  but supposing you wanted a sort of relaxed equality
> wherein, if you chould check for equality on the second element, you
> would, otherwise you would just check the first element.  i would want
> to say something like:
>
> instance (Eq a, Not (Eq b)) => Eq (MyPair a b) where
>     (MyPair a _) == (MyPair a' _) = a == a'
>
> But from what you're telling me there's no way to have both of these
> instances, correct?

How about using overlapping instances? Add:

  instance Eq a where
     _ == _ = True

to your program: if there isn't a ``better'' instance, it'll use this one. 
Such an instance declaration is inherently dangerous to have around, but
might help your particular situation.

Some tests:

Main> MyPair 1 2 == MyPair 1 3
False
Main> MyPair 1 (\x -> x+1) == MyPair 1 (\x -> x+12)
True

Don't forget to start hugs with flags: +o -98
(I haven't tried with ghc.)

Admittedly, this is quite horrible and should be avoided if possible.

-Levent.