在GHCI中,id
的类型为:
Prelude> :t id
id :: a -> a
但是,如果我定义自己的id
函数,为什么类型变量t
的名称? t
和a
之间有区别吗?
Prelude> let identity x = x
Prelude> :t identity
identity :: t -> t
答案 0 :(得分:8)
a
和t
之间没有区别,它们被称为类型变量,代表您可以拥有的任何类型。请注意,它们是用小写字母书写的,其中类型在开头用大写字母书写(除了具有特殊语法的列表)。
此外,如果您编写文件并通过ghci testmodule.hs
module Testmodule where
identity :: b -> b
identity x = x
然后ghci将向您显示您在定义中使用的字母。
答案 1 :(得分:6)
这实际上和我要求的答案相同
如果我将您自己的版本定义为
Prelude> let identity' q = q
为什么值变量q
的名称?q
和x
之间有区别吗?
关于参数变量的关键一点是它们的名称基本上是任意。它是lambda演算的基本属性:α-equivalence。我们只是将\x -> x
替换为\q -> q
(或者,以lambda样式,λx.x
替换为λq.q
)。确实,类型变量也是参数,尽管它们看起来并不像它们。但在幕后,Haskell多态签名应该被理解为System F,所以我们确实Λα . α -> α
,通常写成forall a . a -> a
。这显然相当于forall t . t -> t
。