我对类型构造函数,类型常量和类型变量之间的区别感到困惑.
Haskell 98报告称有4种类型的表达式:
那么什么是类型常数?该报告称"Char,Int ...是类型常量",但我找不到更详细的例子.更令人困惑的是,如何IO
首先将其称为"一元类型构造函数",然后将其称为"常量IO".
我问的原因是因为本文关于Haskell的类型系统实现.在其中,它说:
Haskell类型表达式是类型变量或常量(每个都有相关的类型),或者是一种类型到另一种类型的应用程序:将类型k1 - > k2应用于类型k1的类型生成类型k2
它说的不同于报告.第二种类型的表达式是"构造函数"还是"常量"?
该文件还包括显示代表性的代码:
data Type = TVar Tyvar | TCon Tycon | TAp Type Type | TGen Int
deriving Eq
data Tyvar = Tyvar Id Kind
deriving Eq
data Tycon = Tycon Id Kind
deriving Eq
Run Code Online (Sandbox Code Playgroud)
显然Tycon
代表"型构造,"但当时是什么TCon
表现?怎么样Tyvar
和TVar
?为什么需要分开T
和Ty
?
最后一个问题
显然Tycon代表"类型构造函数",但TCon代表什么?Tyvar和TVar怎么样?为什么需要分开T和Ty?
第一.
在"T"的TCon
,TVar
等仅仅是一个标志是,关注的是类型和他们类型的构造Type
.TCon
取一个类型的值Tycon
并Type
从中构造一个类型的值等.构造函数Type
没有前缀,Ty
而只是T
为了避免混淆,类型可能已被定义
data Type = Tyvar Tyvar | Tycon Tycon | ...
Run Code Online (Sandbox Code Playgroud)
因为值构造函数和类型存在于不同的名称空间中,但这会为更加混乱开辟道路.
1输入变量
是可以用其他类型表达式替换的类型表达式,它们的标识符以小写字母开头(或者它们可以是不以':'开头的符号).
2键入构造函数
是类型表达式采取零个或多个类型表达式参数来构造型种*
,例如
是nullary类型构造函数,它们采用零类型表达式参数来构造一种类型*
,这些也是类型常量.
是一元类型构造函数,它们采用一种类型表达式(*
在这些示例中是类型的,但是一元类型构造函数也可以采用其他类型的参数).
是二进制类型构造函数,
是一个三元类型的构造函数,取两种类型*
和一种类型的论据* -> *
(StateT
因此是这种类型StateT :: * -> (* -> *) -> * -> *
).
3键入应用程序
是表单的类型表达式t1 t2
.如果t2
有种类k2
和t1
有种类k2 -> k3
(类似于功能应用),它只是格式良好.例如StateT s
,类型应用程序,类型表达式StateT
应用于类型变量s
.
4括号类型
是括号中的类型表达式,可能是优先级解析或解析所必需的,否则它与未表示的类型表达式相同,例如
instance Monad (Either e) where ...
Run Code Online (Sandbox Code Playgroud)
括号型表达(Either e)
是相同的Either e
,但括号是必需的,以从两参数类用于两个类型表达式的实例区分开来Either
并e
.在类型中
StateT s ((->) a) b
Run Code Online (Sandbox Code Playgroud)
周围的括号(->) a
是为了优先.(注意,该类型构造(->)
不是由类型构造用大写字母开头的一般规则覆盖,作为一个特殊的情况下[]
,(,)
,(,,)
等)
现在,输入常量.这些只是不包含类型变量的类型表达式,但我不认为它在任何地方都是正式定义的.因此,只有大写字母标识符(包括启动与符号":")的任何类型的表达式和特殊情况下([]
,(->)
,(,)
,...)是一种不变.
在类型理论中,"类型构造函数"通常是指更高类型的类型表达式.通过扩展,普通类型通常作为退化情况包括在内.
在编程语言中,"类型构造函数"通常使用更具体的含义,指的是由上下文定义的命名类型构造函数.同样,这可以包括普通类型作为零参数的退化情况.
术语"类型常数"稍微不那么标准.在Haskell定义中,它似乎非常非正式地使用,并且可能意味着表示由语言预定义的命名类型构造函数的子集(与用户定义的类型构造函数相对,它是根据代数定义的)类型和预定义类型构造函数).因此,每个常量也是一个类型构造函数.
对于"T"vs"Ty",这似乎只是您正在查看的代码片段中的命名约定,旨在区分语言级数据构造函数("T")和语言级类型构造函数("泰").将它分解为单独的类型定义Tycon
并将其Tyvar
分解为单独的类型定义的原因可能是它们被某些代码单独使用.