Skip to content

"Instance head is not headed by a class" error message is less clear than message for type family use corner case

Summary

Consider this code:

data MyType
type MyConstraint x = Eq x
deriving stock instance MyConstraint MyType

GHC produces clear explanation in error message:

Illegal instance for a type synonym
A class instance must be for a class

But when I run this:

deriving stock instance forall (c :: Type -> Constraint). c MyType

Or even more simple example:

deriving stock instance forall (c :: Constraint). c

GHC produces much less clear comment:

Instance head is not headed by a class: c MyType

It seems to me that the problem is not related to "headed by a class". Trick with (c' ~ c MyType, .. does not work in that case.

Why would one need this code? I tried to derive Some wrapper constraints from wrapped class. In my case:

import Data.Kind

data EntityKind x -- Ommited GADT
class Entity x  -- Ommited class

data Some (container :: Type -> Type)
  = forall entity.
    Entity entity =>
    MkSome (EntityKind entity) (container entity)


deriving stock instance
  forall (x :: Constraint) (c :: Type -> Constraint) (container :: Type -> Type) .
  (forall entity. (Entity entity, c entity) => c (container entity), c (Some container) ~ x) => x

Proposed improvements or changes

I do not know. If forall c. does not make sense, than not clear error is probably not important. But my deriving case seems possible in principle. Is not it?

Maybe I am missing some previous issues, but they did not take such QuantifiedConstraints usage into account.

Environment

  • GHC version used: 9.6.1
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information