2014-03-29 98 views
2

在GHCI ID功能的id类型是:类型在Haskell

Prelude> :t id 
id :: a -> a 

但是,如果我定义我自己id功能,为什么类型的名称变量tta之间有区别吗?

Prelude> let identity x = x 
Prelude> :t identity 
identity :: t -> t 

回答

8

at没有什么区别,他们被称为类型变量,代表任何类型的,你可以有。请注意,它们是用小写字母编写的,其中类型在开始处以大写字母书写(除了具有特殊语法的列表以外)。

此外,如果你写一个文件,并将其加载到GHCI通过ghci testmodule.hs

module Testmodule where 

identity :: b -> b 
identity x = x 

然后ghci的会告诉你到底你在定义中使用的信。

+1

重要的是t - > t类型保持不变。这是想要的行为id功能 – arnoapp

+3

此外,我觉得它有助于精神上用'id :: forall a替换id :: a - > a'。 a - > a'。这样就清楚了类型变量绑定(声明)的位置。 – projedi

6

这实际上具有相同的答案,如果我在问

如果我定义我自己的版本的版本

Prelude> let identity' q = q

为什么是值的名称变量 qqx之间有区别吗?

对一般的参数变量关键的一点是,他们的名字基本上都是任意。这是lambda-calculus的基本属性:α-equivalence。我们仅仅用替换为\q -> q(或者,在lambda风格中,λx.xλq.q)。实际上,类型变量也是参数,尽管它看起来并不像它们。但是在引擎盖下,Haskell多态签名应该被读作System F,所以我们真的有Λα . α -> α,通常写成forall a . a -> a。这显然相当于forall t . t -> t

+0

影响类型变量名称的标识q = q为false。类型变量名称与定义中使用的变量名称无关。 –

+1

@ AlainO'Dea在这个答案中他没有说或暗示任何地方。 – Cubic

+0

@ AlainO'Dea:确实;请正确阅读! (不可否认,缺少引号内代码片段的额外颜色支持并不能帮助我(为了使意图更清晰一些,我对其进行了重新格式化),但是我仍然无法看出您如何错误地说出关于类型和价值级别的范围。) – leftaroundabout