是type variable和type parameter哈斯克尔是一回事吗?例如:
ghci> :t last
last :: [a] -> a
Run Code Online (Sandbox Code Playgroud)
a是type variable和type parameter.
以下是类型级术语的缩写语法:
type ::= variable
| type type
| constructor
| "(" type ")"
var ::= <lowercase letter>*
constructor ::= <uppercase letter><lowercase letter>*
| "->"
| "[]"
Run Code Online (Sandbox Code Playgroud)
这是新数据类型声明的缩写语法:
decl ::= "data" constructor var* "=" branches
branches ::= branch | branch "|" branches
branch ::= constructor type*
Run Code Online (Sandbox Code Playgroud)
这不是很精确或完整(请参阅报告中的规范细节),但这足以让讨论开始.
这里有一些术语和我说的时候的意思:
var上面的作品构建的类型级术语; 例如a,graph,foo将被罚款类型变量,如果他们出现在上下文期待一个类型,但是[a],Tree,Ord x不是类型变量,graph不会在术语声明一个类型变量f graph = undefined.var参数; 例如,data Foo a b c = Bar a Int我会打电话的a,b和c到左=类型的参数,但a在右边不会.在较小的程度上,"类型参数"也被用来表示"类型参数",见下文,尽管这种用法在我看来有点草率.type ::= type type上面制作的第二部分的类型; 例如Foo (Maybe a),我会叫a一个类型参数和(Maybe a)类型参数,但Foo并Maybe不会是.作为一个特例,我们[a]作为应用程序的一种语法糖[] a; 在这种情况下,a即使它处于一个有趣的位置,我也会调用一个类型参数.记住这个术语,在类型中[a] -> a,我肯定会调用a一个类型变量; 我会反对调用a一个类型参数; 我可以调用a一个类型参数(因为它用于[] a以含糖样式编写的类型应用程序).
请注意,即使在这种情况下,人们可能会调用a这两个类型变量和类型参数但这并不意味着这两个术语是同义的!说这a是一个类型变量指出它尚未具体化,而说这a是一个类型参数指出它被用来填充其他类型的参数 - 这强调两个非常不同关于a那种类型的事情!
只是为了通过一些证明条款之间差异的例子来完善答案,请考虑从Prelude中获取的这些类型声明:
undefined :: a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
not :: Bool -> Bool
otherwise :: Bool
Run Code Online (Sandbox Code Playgroud)
该a在的类型undefined是一种类型的可变但不是类型参数; 同样m,类型中的类型(>>=)是一个类型变量,但在大多数地方它出现的不是类型参数.
类型参数Bool中的两种外观not都是类型参数,但不是类型变量.(就像类型[t]是糖[] t,类型t1 -> t2是糖(->) t1 t2.)
该a和b在类型(>>=)的类型都是变量和类型参数.
该Bool在的类型otherwise既不是类型变量也不是一个类型参数.