Can a class define a default superclass function?

Graham Klyne gk@ninebynine.org
Thu, 01 May 2003 16:00:35 +0100


It appears that it is not possible for a subclass to define a default
for one of its superclass functions.

In the example below, simply trying to declare the default method for (==) 
results in
the error 'No member "==" in class "Pair"', which I think is consistent 
with [1].

But trying to include a signature for (==) in the specification of Pair
results in a type error:
   Inferred type is not general enough
   *** Expression    : eqPair
   *** Expected type : Pair a b c => a b c -> a b c -> Bool
   *** Inferred type : Pair a (b c d) (e f g) => a (b c d) (e f g) -> a (b 
c d) (e f g) -> Bool
which also makes sense as (I assume) the new type signature for (==) is 
being picked up when using (==) to compare the component values.

The closest I can see is to declare (say) eqPair as below, then define
   (==) = eqPair
for each instance (as below).  Is this a genuine restriction, or is there 
some way to avoid this?

#g
--

[1] http://haskell.org/onlinereport/decls.html#sect4.3.1

Example code:
[[
--  Can a class define a default superclass method?
class (Eq (a k v), Eq k, Eq v) => Pair a k v where
     newPair :: (k,v) -> a k v
     getPair :: a k v -> (k,v)
     eqPair  :: a k v -> a k v -> Bool
     eqPair p1 p2 = (k1==k2) && (v1==v2) where
         (k1,v1) = (getPair p1)
         (k2,v2) = (getPair p2)
     -- or just:
     -- eqPair p1 p2 = (getPair p1) == (getPair p2)

     -- But can't say this:
     -- (==) :: a k v -> a k v -> Bool
     -- (==) = eqPair

--  The simplest way I can see to define this is to define
--  (==) per-instance using the default eqPair method of
--  the Pair class, thus:

newtype MyPair k v = P1 (k,v)
instance (Eq k, Eq v) => Pair MyPair k v where
     newPair (x,y)      = P1 (x,y)
     getPair (P1 (x,y)) = (x,y)

instance (Eq k, Eq v) => Eq (MyPair k v) where
     (==) = eqPair
]]


-------------------
Graham Klyne
<GK@NineByNine.org>
PGP: 0FAA 69FF C083 000B A2E9  A131 01B9 1C7A DBCA CB5E