[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.
More information about the Haskell-Cafe