On Fri, Mar 18, 2011 at 13:35, JP Moresmau wrote:
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