浏览各种包的haddock时,我经常会看到如下的实例文档(Control.Category):
Category k (Coercion k)
Category * (->)
或者这个(Control.Monad.Trans.Identity):
MonadTrans (IdentityT *)
这里的善意签名到底是什么意思?它没有出现在源代码中,但我已经注意到它似乎出现在使用PolyKinds扩展的模块中。我怀疑它可能像一个TypeApplication,但有一种。因此,例如,最后一个例子意味着,如果IdentityT
的第一个自变量具有*
类型,则它是一个monad转换器。
所以我的问题是:
- 我的解释正确吗?这种签名到底指的是什么
- 在第一个
Category
实例中,我怎么知道k
是一种而不是一种类型?还是我只需要知道Category
的arity - 与此语法类似的源代码是什么
我不是在要求对种类做出解释。
引用Richard Eisenberg最近在haskell咖啡馆邮件列表上的帖子:
Haddock有时在启用
-XPolyKinds
的情况下难以渲染类型。问题是GHC通常不需要编写类参数,也不会将它们打印出来(除非您说-fprint-explicit-kinds
)。但我相信,每当-XPolyKinds
打开时,Haddock就会打印出种类。所以这两个不同的定义实际上是一样的:只是一个模块有-XPolyKinds
,另一个没有。
*
是一种普通类型。所以Int
有*
(我们写Int :: *
),而Maybe
有* -> *
。Typeable
实际上有一种forall k. k -> Constraint
,这意味着它是多元化的。在下面的第一个代码段中,Typeable
的*
参数将k
实例化为*
,因为类型变量a的类型为*
。
是的,正如您所猜测的,它与PolyKinds
有关。Haddock用一种"显式类型应用程序"来渲染这些poly-kinded类型。恰好Category
是poly-kinded的,具有forall k. (k -> k -> *) -> Constraint
类型,因此Haddock在每个实例旁边呈现该类型的应用程序。
在我看来,这是Haddock的一个bug或错误特性,因为据我所知,没有等效的模拟源代码。这很令人困惑,我不知道有什么比识别它通常的表现方式并从上下文中直观地推断出发生了什么更好的方法来理解它。