1

什么样的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有两种具体类型作为参数 (StringInt)。 g有一个参数 ( Bool) 这两个都是 的参数T。所以我有:(*->*->*)->(*->*)->*。这个对吗?谢谢

4

2 回答 2

4

GHCi 可以告诉你各种各样的事情。例如,如果您输入:

data T f g = T (f String Int) (g Bool)

在一个文件Kinds.hs中,您可以将其加载到 GHCi 中并询问以下内容T

> :l Kinds.hs
> :k T
T :: (* -> * -> *) -> (* -> *) -> *
>

所以看起来 GHCi 同意你的解决方案。

对于您的第一个问题,您不能要求 GHCi 直接告诉您 kind of f,但由于f是 typeclass 的参数C,您可以要求 kind of C

> :k C
C :: (* -> * -> *) -> Constraint
>

意思是C需要一种类型* -> * -> *来产生约束。所以,GHCi 不同意你的观点,并认为这f是善意的* -> * -> *

查看类型签名:

comp :: f b c -> f a b -> f a c

请注意,您不能拥有fkind (* -> *) -> * -> *,因为f b c这意味着那b是 kind* -> *f a b意味着 that bof kind *,并且不能两者兼而有之。

事实证明,最普遍的可能类型是:

f :: k -> k -> *

其中前两个参数被迫具有相同的种类,因为在k两个位置b(分别使用 inf a b和有意义。f b c*f b cf a bf a ccomp

但是,Haskell98(无扩展)不会推断出最一般的可能种类,因此它选择kbe *,给出种类签名* -> * -> *。事实证明,如果您启用某个扩展 ( PolyKinds),则将k -> k -> *改为使用 kind 签名。

于 2017-12-21T23:14:44.223 回答
2

对于第一个问题,我不明白您为什么决定使用akind * -> *。从所写的内容来看,a只是一个*,仅此而已。因此,种类f* -> * -> *

对于第二个问题,你是对的。

于 2017-12-21T23:03:28.573 回答