在Foldable
文档,我看到以下实例:
(Foldable f, Foldable g) => Foldable (Compose * * f g)
如果我查看 Compose 的定义,我看到它被声明为
newtype Compose f g a = Compose f (g a)
它有种类 (* -> *) -> (* -> *) -> * -> *
,对吧? (我想这是推断的)。现在据我所知,我想这样写是正确的:
(Foldable f, Foldable g) => Foldable (Compose f g)
因为 Compose f g
也有种类 * -> *
。但是,我猜这两个 kind
标识符的存在是有原因的。但这是什么原因呢?
最佳答案
从技术上讲,如果您打开 PolyKinds
,Compose
的类型会更通用:
newtype Compose (f :: k -> *) (g :: k' -> k) (a :: k') = Compose (f (g a))
此类型由 PolyKinds
推断并需要它写入(并且它在 library 中这样定义 - 请注意 PolyKinds
在模块中启用) .
从技术上讲,这
Compose
有两个kind 参数,它们是隐式的。这意味着您通常不会指定它们,通常也看不到它们。然而,黑线鳕的一个特点是它们确实显示了种类参数。但是如果你有兴趣,你可以在 GHCi 中看到同样的东西,例如
>:set -fprint-explicit-kinds
>import Data.Functor.Compose
>:i Compose
type role Compose nominal nominal representational nominal nominal
newtype Compose k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1)
= Compose {getCompose :: f (g a)}
-- Defined in `Data.Functor.Compose'
....
instance [safe] (Foldable f, Foldable g) =>
Foldable (Compose * * f g)
请注意,Compose
有两种类型的参数 - *
和 *
- 因为 f
和 由于
必须是 Functor
约束,g* -> *
类型。
关于haskell - 星号(种类,*)在这个Foldable实例中的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39795779/