在GHCI ID功能的id
类型是:类型在Haskell
Prelude> :t id
id :: a -> a
但是,如果我定义我自己id
功能,为什么类型的名称变量t
? t
和a
之间有区别吗?
Prelude> let identity x = x
Prelude> :t identity
identity :: t -> t
在GHCI ID功能的id
类型是:类型在Haskell
Prelude> :t id
id :: a -> a
但是,如果我定义我自己id
功能,为什么类型的名称变量t
? t
和a
之间有区别吗?
Prelude> let identity x = x
Prelude> :t identity
identity :: t -> t
有a
和t
没有什么区别,他们被称为类型变量,代表任何类型的,你可以有。请注意,它们是用小写字母编写的,其中类型在开始处以大写字母书写(除了具有特殊语法的列表以外)。
此外,如果你写一个文件,并将其加载到GHCI通过ghci testmodule.hs
module Testmodule where
identity :: b -> b
identity x = x
然后ghci的会告诉你到底你在定义中使用的信。
这实际上具有相同的答案,如果我在问
如果我定义我自己的版本的版本
Prelude> let identity' q = q
为什么是值的名称变量q
?q
和x
之间有区别吗?
对一般的参数变量关键的一点是,他们的名字基本上都是任意。这是lambda-calculus的基本属性:α-equivalence。我们仅仅用替换为\q -> q
(或者,在lambda风格中,λx.x
与λq.q
)。实际上,类型变量也是参数,尽管它看起来并不像它们。但是在引擎盖下,Haskell多态签名应该被读作System F,所以我们真的有Λα . α -> α
,通常写成forall a . a -> a
。这显然相当于forall t . t -> t
。
影响类型变量名称的标识q = q为false。类型变量名称与定义中使用的变量名称无关。 –
@ AlainO'Dea在这个答案中他没有说或暗示任何地方。 – Cubic
@ AlainO'Dea:确实;请正确阅读! (不可否认,缺少引号内代码片段的额外颜色支持并不能帮助我(为了使意图更清晰一些,我对其进行了重新格式化),但是我仍然无法看出您如何错误地说出关于类型和价值级别的范围。) – leftaroundabout
重要的是t - > t类型保持不变。这是想要的行为id功能 – arnoapp
此外,我觉得它有助于精神上用'id :: forall a替换id :: a - > a'。 a - > a'。这样就清楚了类型变量绑定(声明)的位置。 – projedi