Haskell种类。初学者

问题描述 投票:1回答:2

什么是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的参数。所以我有:(*->*->*)->(*->*)->*。它是否正确?谢谢

haskell functional-programming data-kinds
2个回答
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用于两个位置(分别在f a bf b c),最终结果被迫有类*因为f b cf a bf a c都需要具体类型,以便comp的类型签名有意义。

然而,Haskell98(没有扩展)并没有推断出最普​​遍的可能类型,因此它选择k*,给出类型签名* -> * -> *。事实证明,如果你启用某个扩展(PolyKinds),那么种类签名将是k -> k -> *


2
投票

对于第一个问题,我不明白你为什么认为a有善意的* -> *。根据所写的,a只是一个*,仅此而已。因此,f的种类是* -> * -> *

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

© www.soinside.com 2019 - 2024. All rights reserved.