[Haskell-cafe] Supplying a default implementation for a typeclass based on another class

wren ng thornton wren at freegeek.org
Mon Mar 2 00:23:04 EST 2009


Svein Ove Aas wrote:
> Martin Huschenbett wrote:
> >
> >> instance (Show a,Read a) => Binary a where
> >>  put = put . show
> >>  get = fmap read get
> > But then you will need the following language extensions: FlexibleInstances,
> > OverlappingInstances, UndecidableInstances
>
> Well, isn't there a good chance it'll end up picking that instance
> even when a more specific one is available, then?
> 
> I think the problem here is that I don't know of any way to inform GHC
> that any particular instance is "less specific".

OverlappingInstances will allow more specific instances to be defined, 
and will select them when appropriate. Where "specific" has to do with 
the usual type unification algorithm. This instance is on a type 
variable, hence is the least specific. An instance on (Maybe a), (Either 
a b), etc would all be more specific. Instances on (Maybe Int), (Either 
Bool b), (Either a Double) would be more specific still.

Aside: Depending on how you're using this, we can run into problems 
with, say, (Either Bool Double). Does it fall under (Either Bool b) or 
under (Either a Double)? By default, OverlappingInstances requires that 
you manually resolve this diamond issue (i.e. by defining an instance 
for (Either Bool Double) which is more specific than all other options). 
The IncoherentInstances option tells the compiler to deal with the 
ambiguity itself, which means it will pick the most specific instance 
which does not introduce ambiguity (i.e. the other end of the diamond; 
in this case, the instance for the fully unspecified type variable). 
Obviously, incoherence generally does not mean what you want.

The UndecidableInstances is because the two elements of the context are 
not "smaller" than the head (Binary a), and hence the compiler cannot 
guarantee that progress is being made when it backward-chains to find 
those instances. To witness why this could be a problem, imagine an 
instance for Show or Read which took Binary in the context.

-- 
Live well,
~wren


More information about the Haskell-Cafe mailing list