4

When enabling PolyKinds, previously valid type signatures can become invalid.

The following code compiles without PolyKinds.

{-# LANGUAGE KindSignatures #-}
import GHC.Generics

foo :: Constructor c => t c (f :: * -> *) a -> [Char]
foo = conName

When I enable PolyKinds it fails to compile.

Kind incompatibility when matching types:
  t0 :: * -> (* -> *) -> * -> *
  t :: * -> (* -> *) -> k -> *
Expected type: t c f a -> [Char]
  Actual type: t0 c f a0 -> [Char]
Relevant bindings include
  foo :: t c f a -> [Char] (bound at Gen.hs:8:1)
In the expression: conName
In an equation for ‘foo’: foo = conName

Is there a way to give a type signature for foo when PolyKinds is enabled?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
user1078763
  • 728
  • 5
  • 15
  • `foo :: Constructor c => (t :: * -> (* -> *) -> * -> *) c (f :: * -> *) a -> [Char]` works, bug or feature? – user1078763 Jul 11 '15 at 05:40
  • Yeah, that should work too, since the kinds are inferred from place to place within the signature it doesn't matter on which type variable you fix it. – Ørjan Johansen Jul 11 '15 at 05:47

1 Answers1

4

Note that the discrepancy is

t0 :: * -> (* -> *) -> * -> *
t :: * -> (* -> *) -> k -> *

That is, in one of the signatures GHC thinks that the third argument of t should have kind *, and in the other it thinks it should have polymorphic kind k.

I think that the former signature (with *) comes from conName, while the latter with k implicitly comes from your signature for foo – the k appears because now that you have PolyKinds enabled, all your type signatures are interpreted with polymorphic kinds when possible. Also, by design, a signature is considered to give the the full "API" for a function, which means no attempt to infer the kind from the rest of the function is done when you specify the signature explicitly.

In your signature the third argument of the t type is a, so you can fix it by adding a kind annotation to that to make it consistent with what conName wants:

foo :: Constructor c => t c (f :: * -> *) (a :: *) -> [Char]
foo = conName
Ørjan Johansen
  • 18,119
  • 3
  • 43
  • 53