4

这可能是一个愚蠢的问题,但我无法弄清楚以下行为的基本规则:

foo :: t (f a) -> f a b -- accepted
foo = undefined

bar :: t [f a] -> f a b -- rejected
bar = undefined

f应用到aa b分别bar导致类错误并因此被拒绝是完全有道理的。但为什么会被foo接受?

4

1 回答 1

10

是那种f

由于返回类型f a b- 即f应用于两个参数, - 这意味着f :: Type -> Type -> Type.

但是 thenf a被用作列表元素[f a]- 并且列表元素必须是Type,这意味着f a :: Type,这意味着f :: Type -> Type

不匹配。


foo之所以有效,是因为可以部分应用类型。也就是说,如果f :: Type -> Type -> Type,那么f a :: Type -> Type。然后, typet允许有一个参数 kind Type -> Type,所以一切都匹配。


重申上述内容:

  • foo有效,因为 typet可能有一个参数 kind Type -> Type
  • bar不起作用,因为 type [](aka "list") 必须有一个参数 kind Type
于 2021-09-08T20:04:24.007 回答