“Illegal type synonym family application in instance” with functional dependency

Viewed 2000

I have a multi-parameter typeclass with a functional dependency:

class Multi a b | a -> b

I also have a simple, non-injective type synonym family:

type family Fam a

I want to write an instance of Multi that uses Fam in the second parameter, like this:

instance Multi (Maybe a) (Fam a)

However, this instance is not accepted. GHC complains with the following error message:

error:
  • Illegal type synonym family application in instance: Fam a
  • In the instance declaration for ‘Multi (Maybe a) (Fam a)’

Fortunately, there is a workaround. I can perform a usual trick for moving a type out of the instance head and into an equality constraint:

instance (b ~ Fam a) => Multi (Maybe a) b

This instance is accepted! However, I got to thinking, and I started to wonder why this transformation could not be applied to all instances of Multi. After all, doesn’t the functional dependency imply that there can only be one b per a, anyway? In this situation, it seems like there is no reason that GHC should reject my first instance.

I found GHC Trac ticket #3485, which describes a similar situation, but that typeclass did not involve a functional dependency, so the ticket was (rightfully) closed as invalid. In my situation, however, I think the functional dependency avoids the problem described in the ticket. Is there anything I’m overlooking, or is this really an oversight/missing feature in GHC?

0 Answers
Related