是"类型变量" "类型参数"的别名?

时间:2016-01-14 01:05:15

标签: haskell

Haskell中的type variabletype parameter是一样的吗?例如:

ghci> :t last
last :: [a] -> a

a同时为type variabletype parameter

1 个答案:

答案 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制作以上制作的类型级字词;例如,agraphfoo如果出现在期望某种类型的上下文中,则为精细类型变量,但[a]Tree,{{ 1}}不是类型变量,Ord x在术语声明graph中不是类型变量。
  • 类型参数:数据声明中的位置,指向f graph = undefined个参数之一;例如,在var中,我会调用data Foo a b c = Bar a Int类型参数左侧的abc,但是=右边不会。在较小的程度上,“类型参数”也被用来表示“类型参数”,见下文,虽然这种用法在我看来有点草率。
  • 类型参数:填写上述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]的糖而言,类型[] tt1 -> t2的糖。)

(->) t1 t2类型中的ab都是类型变量和类型参数。

(>>=)类型中的Bool既不是类型变量也不是类型参数。