在Haskell中,我了解到有类型变量(例如id :: a -> a
),适用于类型签名,以及种(例如{{1}应用于类型构造函数和类型类。类型必须具有种类Maybe :: * -> *
(是具体类型)才能保存值。
我们使用类型变量来启用多态:*
意味着常量Nothing :: Maybe a
可以属于一系列可能的类型。这使我相信kinding和类型变量具有相同的目的;不会将最后一个代码示例工作为简单Nothing
,其中类型类Maybe仍然保留Nothing :: Maybe
类型以表示该类型属于泛型族?
我们正在做的是采用一个空参数(* -> *
)并用表示相同方差水平的类型变量(* -> *
)填充它。
我们在另一个例子中看到了这种行为:
a
为什么理论上有必要对种类和类型变量进行区分?
答案 0 :(得分:5)
它们与打字和通常(价值级别)变量截然不同。变量具有类型,但它们不是类型。同样,键入变量有种类。类型变量是主要的概念:没有它们你没有参数多态,它们也存在于许多其他语言中,如Java,C#等。但Haskell进一步允许类型 - 采取参数({{1} },[]
,Maybe
等)独立存在并具有表示此类非具体类型的类型变量。这意味着它需要一种类型的系统来禁止像->
这样的东西。
从示例中,您似乎建议您可以编写没有类型变量的签名,并将其恢复为签名。但那你怎么能区分Maybe Int Int
和a -> b -> a
?