These are GHC types, but here is a self-contained example:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
FlexibleInstances #-}
data Id=Id String
data Result id =ResultId Id
| ResultGen id
data Sig id=IdSig Id
| SigGen id
class Search id a | a -> id where
search :: a -> Result id
instance Search Id Id where
search i = ResultId i
instance (Search id id) => Search id (Sig id) where
search (SigGen g) = search g
search (IdSig i) = search i
The last line fails. I don't understand why this doesn't compile.
This doesn't even work in GHC 6.12.3. The search call in the second case, IdSig, restricts the result to Result Id, which is less polymorphic than Result id. Either of the following are valid:
instance Search Id (Sig Id) where
search (SigGen g) = search g
search (IdSig i) = search i
instance (Search id id) => Search id (Sig id) where
search (SigGen g) = search g
Sean