如何在启用PolyKinds时为多态函数提供类型签名?

时间:2015-07-11 05:28:51

标签: haskell ghc generic-programming

启用PolyKinds时,之前有效的类型签名可能会失效。

以下代码编译时没有PolyKinds

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

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

当我启用PolyKinds时,它无法编译。

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

启用foo时,有没有办法为PolyKinds提供类型签名?

1 个答案:

答案 0 :(得分:5)

请注意,差异是

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

也就是说,在其中一个签名中,GHC认为t的第三个参数应该有*种,而另一个认为它应该具有多态类k。< / p>

我认为前签名(*)来自conName,后者k隐含来自foo的签名 - {{1因为现在您已启用k,所以您的所有类型签名都会在可能的情况下使用多态类型进行解释。此外,根据设计,签名被认为是为函数提供完整的“API”,这意味着当您明确指定签名时,不会尝试从函数的其余部分推断出类型。

在您的签名中,PolyKinds类型的第三个参数是t,因此您可以通过添加类型注释来修复它,使其与a想要的内容保持一致:< / p>

conName