在GHCI中,类型id
是:
Prelude> :t id id :: a -> a
但是,如果我定义自己的id
函数,为什么是类型变量的名称t
?有没有之间的差异t
和a
?
Prelude> let identity x = x Prelude> :t identity identity :: t -> t
epsilonhalbe.. 8
a
和之间没有区别t
,它们被称为类型变量,代表您可以拥有的任何类型.请注意,它们是用小写字母书写的,其中类型在开头用大写字母书写(除了具有特殊语法的列表).
另外,如果您编写一个文件并将其加载到ghci中 ghci testmodule.hs
module Testmodule where identity :: b -> b identity x = x
然后ghci将向您显示您在定义中使用的字母.
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演算的基本属性:α等价.我们只是替换\x -> x
为\q -> q
(或者,以lambda-style,?x.x
with ?q.q
).确实,类型变量也是参数,尽管它们看起来并不像它们.但在引擎盖下,Haskell多态签名应该被理解为系统F,所以我们?? . ? -> ?
通常都会编写forall a . a -> a
.这显然相当于forall t . t -> t
.