f
是什么类型的?
class C f where
comp :: f b c -> f a b -> f a c
我写过:(* -> *) -> * -> *
它是否正确? c
是具体类型*
。 a
是一种采用类型并生成类型的类型。这两个都是f
的参数?我的论证是否正确?
什么是T
?
data T f g = T (f String Int) (g Bool)
f
有两个具体类型作为参数(String
和Int
)。 g
有一个参数(Bool
)这两个参数都是T
的参数。所以我有:(*->*->*)->(*->*)->*
。
它是否正确?谢谢
答案 0 :(得分:3)
GHCi可以告诉你各种各样的事情。例如,如果你把:
data T f g = T (f String Int) (g Bool)
在文件Kinds.hs
中,您可以将其加载到GHCi中并询问T
的种类:
> :l Kinds.hs
> :k T
T :: (* -> * -> *) -> (* -> *) -> *
>
所以看起来GHCi同意你的解决方案。
对于您的第一个问题,您不能要求GHCi直接告诉您f
的类型,但由于f
是类型类C
的参数,您可以要求那种C
:
> :k C
C :: (* -> * -> *) -> Constraint
>
意味着C
采用类型* -> * -> *
来生成约束。所以,GHCi不同意你的看法,认为f
属于* -> * -> *
。
查看类型签名:
comp :: f b c -> f a b -> f a c
请注意,您f
种类(* -> *) -> * -> *
,f b c
意味着b
* -> *
f a b
b
*
会暗示f :: k -> k -> *
k
种b
,而且不能同时存在。{/ p>
事实证明,最常见的可能是:
f a b
前两个参数被强制使用相同类型f b c
,因为*
用于两个位置(分别在f b c
和f a b
中)和最后一个结果被强制使用f a c
,因为comp
,k
和*
都需要具体类型才能生成* -> * -> *
的类型签名感。
但是,Haskell98(没有扩展名)不会推断出最常见的类型,因此它会选择PolyKinds
为k -> k -> *
,并提供类型签名println(apply3(1,2,3,::plus2))
。事实证明,如果您启用某个扩展程序({{1}}),则类型签名将为{{1}}。
答案 1 :(得分:2)
对于第一个问题,我不明白您为什么认定a
有* -> *
种。根据所写内容,a
只是*
,仅此而已。因此,f
的种类为* -> * -> *
。
对于第二个问题,你是对的。