Haskell中的type variable
和type parameter
是一样的吗?例如:
ghci> :t last
last :: [a] -> a
a
同时为type variable
和type parameter
。
答案 0 :(得分:9)
以下是类型级术语的缩写语法:
type ::= variable
| type type
| constructor
| "(" type ")"
var ::= <lowercase letter>*
constructor ::= <uppercase letter><lowercase letter>*
| "->"
| "[]"
这是新数据类型声明的缩写语法:
decl ::= "data" constructor var* "=" branches
branches ::= branch | branch "|" branches
branch ::= constructor type*
它不够精确或完整(请参阅Report了解规范细节),但这足以让讨论开始。
以下是一些术语和我说的时候的意思:
var
制作以上制作的类型级字词;例如,a
,graph
,foo
如果出现在期望某种类型的上下文中,则为精细类型变量,但[a]
,Tree
,{{ 1}}不是类型变量,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
的两个非常不同的东西!
只是通过一些证明条款之间差异的例子来完善答案,考虑从Prelude中获取的这些类型声明:
a
undefined :: a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
not :: Bool -> Bool
otherwise :: Bool
类型中的a
是类型变量,但不是类型参数;同样,undefined
类型中的m
是一个类型变量,但在大多数地方它出现的不是类型参数。
(>>=)
类型中Bool
的两个外观都是类型参数,但不是类型变量。 (就not
类型[t]
的糖而言,类型[] t
是t1 -> t2
的糖。)
(->) t1 t2
类型中的a
和b
都是类型变量和类型参数。
(>>=)
类型中的Bool
既不是类型变量也不是类型参数。