Haskell中id函数的类型
在GHCI中,Haskell中id函数的类型,haskell,Haskell,在GHCI中,id的类型为: Prelude> :t id id :: a -> a 但是如果我定义自己的id函数,为什么类型变量t的名称是?t和a之间有区别吗 Prelude> let identity x = x Prelude> :t identity identity :: t -> t a和t之间没有区别,它们被称为类型变量,代表您可以拥有的任何类型。请注意,它们是用小写字母编写的,而类型的开头是用大写字母编写的(列表除外,列表具有特殊语法) 此外,如
id
的类型为:
Prelude> :t id
id :: a -> a
但是如果我定义自己的id
函数,为什么类型变量t
的名称是?t
和a
之间有区别吗
Prelude> let identity x = x
Prelude> :t identity
identity :: t -> t
a
和t
之间没有区别,它们被称为类型变量,代表您可以拥有的任何类型。请注意,它们是用小写字母编写的,而类型的开头是用大写字母编写的(列表除外,列表具有特殊语法)
此外,如果您通过ghci testmodule.hs
module Testmodule where
identity :: b -> b
identity x = x
然后,ghci将向您展示您在定义中使用的字母。这实际上与我所问的答案相同 如果我将自己的版本定义为
Prelude>let identity'q=q
为什么值变量的名称是
q
?q
和x
之间有区别吗?
一般来说,参数变量的关键是它们的名称基本上是任意的。这是lambda演算的一个基本性质:。我们只是将
\x->x
替换为\q->q
(或者,在lambda风格中,λx.x
替换为λq.q
)。事实上,类型变量也是参数,尽管看起来并不是这样。但是在幕后,Haskell多态性签名应该被理解为,所以我们确实有α。α->α
,通常为所有a编写。a->a
。这显然相当于所有t的。t->t
重要的一点是t->t类型保持不变。这是id函数所需要的行为,因此我发现用id::for all a来替换id::a->a
在心理上是很有帮助的。a->a
。这样就可以清楚地知道类型变量绑定(声明)的位置。影响类型变量名的标识q=q为false。类型变量名与定义中使用的变量名无关。@AlainO'Dea他没有在这个答案的任何地方说或暗示。@AlainO'Dea:确实;请仔细阅读!(不可否认,引号中缺少额外的代码片段颜色支持并没有什么帮助(我重新格式化了代码片段以使意图更加清晰),但我仍然看不出你怎么会把它误认为是关于类型和值级别作用域之间的交互。)重写/重新格式化有很大的不同。投票修正:)我刚刚检查了差异。你清楚地说了值变量,这是正确的。不是我最好的作品。