启用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
提供类型签名?
答案 0 :(得分:5)
请注意,差异是
t0 :: * -> (* -> *) -> * -> *
t :: * -> (* -> *) -> k -> *
也就是说,在其中一个签名中,GHC认为t
的第三个参数应该有*
种,而另一个认为它应该具有多态类k
。< / p>
我认为前签名(*
)来自conName
,后者k
隐含来自foo
的签名 - {{1因为现在您已启用k
,所以您的所有类型签名都会在可能的情况下使用多态类型进行解释。此外,根据设计,签名被认为是为函数提供完整的“API”,这意味着当您明确指定签名时,不会尝试从函数的其余部分推断出类型。
在您的签名中,PolyKinds
类型的第三个参数是t
,因此您可以通过添加类型注释来修复它,使其与a
想要的内容保持一致:< / p>
conName