为什么我只能在类型参数位置传递部分应用的类型构造函数?
Why can I pass partially applied type constructors only in type parameter position?
这可能是一个愚蠢的问题,但我无法弄清楚以下行为的基本规则:
foo :: t (f a) -> f a b -- accepted
foo = undefined
bar :: t [f a] -> f a b -- rejected
bar = undefined
f
在 bar
中分别应用于 a
和 a b
会导致种类错误并因此被拒绝,这是完全合理的。但是为什么 foo
被接受了?
是f
的那种。
由于 return 类型是 f a b
- 即 f
应用于两个参数, - 这意味着 f :: Type -> Type -> Type
.
但是然后f a
被用作列表元素-[f a]
-并且列表元素必须是Type
,这意味着f a :: Type
,这意味着f :: Type -> Type
.
不匹配。
foo
有效,因为可以部分应用类型。也就是说,如果f :: Type -> Type -> Type
,那么f a :: Type -> Type
。然后,允许类型 t
有一个类型为 Type -> Type
的参数,所以一切都匹配。
重申以上:
foo
有效,因为类型 t
可能有一个类型为 Type -> Type
. 的参数
bar
不起作用,因为类型 []
(又名“列表”)必须具有类型 Type
. 的参数
这可能是一个愚蠢的问题,但我无法弄清楚以下行为的基本规则:
foo :: t (f a) -> f a b -- accepted
foo = undefined
bar :: t [f a] -> f a b -- rejected
bar = undefined
f
在 bar
中分别应用于 a
和 a b
会导致种类错误并因此被拒绝,这是完全合理的。但是为什么 foo
被接受了?
是f
的那种。
由于 return 类型是 f a b
- 即 f
应用于两个参数, - 这意味着 f :: Type -> Type -> Type
.
但是然后f a
被用作列表元素-[f a]
-并且列表元素必须是Type
,这意味着f a :: Type
,这意味着f :: Type -> Type
.
不匹配。
foo
有效,因为可以部分应用类型。也就是说,如果f :: Type -> Type -> Type
,那么f a :: Type -> Type
。然后,允许类型 t
有一个类型为 Type -> Type
的参数,所以一切都匹配。
重申以上:
foo
有效,因为类型t
可能有一个类型为Type -> Type
. 的参数
bar
不起作用,因为类型[]
(又名“列表”)必须具有类型Type
. 的参数