类型系统是编程语言的重要组成部分,本文是对
type systemlucacardelli.name的阅读笔记和梗概,强烈推荐感兴趣的同学阅读文章本身。
前置知识
类型系统的目的
类型系统(type system)的基本目标是防止程序在运行时发生类型错误。当且仅当语言运行时不存在任何形式的类型错误,那么它就是sound的。soundness是类型系统研究的重要目标。
对类型系统的描述
描述类型系统使用的是一种符号系统,它来自于自然推演(Natural Deduction)。有如下几个组成部分:
Judgments
Judgement是一条断言,一般具有如下形式:
表示在类型环境
有一条常用的通用断言:
表示类型环境
还有一种语义:
Type rules
类型规则通过一条或多条断言来决定一条断言的正确性,一般有如下形式:
横线上方是一条或多条判断,描述了规则的前提(premise)。下方只能有一个判断,描述了规则的结论(conclusion)。顶部可以标注规则的名称和注释。前提的右边也可以写一些注释。
我们来举个例子:
这个例子认为在一个行为良好的类型环境中,所有的自然数都有类型Nat,两个类型同为Nat的表达式M和N相加的结果也为一个自然数。
有一条基本规则:空的环境是类型良好的,不需要任何假设:
一系列类型规则组成的集合称为一个正式的类型系统。
Type derivations
类型导出(Type derivations)在一个给定的类型系统中,是一颗树,它的底部的根节点和顶部的叶节点都是类型断言,且每条断言都可以由它上方的断言结合类型系统的规则直接获得。给定一个类型断言,我们可以将它放置在类型导出的根部(底部),利用类型规则一步一步向上推导,如果能够顺利推出,说明断言是合法的。
例如根据我们此前的规则,可以判断
Type inference
给定一个项M,如果它在类型环境
System
基础构成
语法
一阶类型化的
断言
对于
规则
有了这三条断言,我们可以写出它的类型规则:
基础类型
我们有了System
Unit Type
Unit Type很常见,在很多语言中它又叫Void
或Null
。
Bool Type
Bool Type也很常见,它是布尔值的类型,它一般拥有一个有用的操作,即通常语言中的if else
语句,我们在这里称为cond
:
在Cond中我们需要通过下标A来告诉类型检查器,结果应该是类型A,来消除潜在的类型检查困难。
Nat Type
Nat Type就是自然数的类型。假设我们有0和Succ
,则1为Succ 0
,2为Succ Succ 0
。Nat还存在两种计算:pred
和isZero
,前者用来得到当前自然数前一位的自然数,后者用来判断自然数是否为0.
结构类型
Product Types
Product Types是一对类型,由两个类型构成,例如
first
和
second
操作符来提取出来。通过
with
语句,我们可以把product type解构为两个单独的变量
Union Types
Union Types指的是结合类型。例如一个union type
isLeft
和
isRight
来进行测试,相应的类型可以由
asLeft
或
asRight
来提取。和之前Bool Type的Cond语句类似,
asLeft
和
asRight
也需要下标来帮助类型检查器进行判断。
如果asRight
被错误的应用在了由isLeft
标记的元素上,那么我们就得到了一个被捕获的异常,这个异常不属于forbidden error。因此有了union Type,我们可以定义一个典型的被捕获的错误类型:
我们可以用它来表示任何类型的异常。
Record Types
Record Types是product types的升级版,它由product types迭代而来。对于record M中的每个组成变量
Variant Types
与recotd types和product的关系类似,variant types也由union types迭代而来。Union types
Reference Types
引用类型在命令式语言中很常见,它用来包裹地址可变的元素。可以由ref
分配,由assign
更新,并由deref
解除。
Recursive Types
递归类型需要为环境中扩展一个类型变量X。类型变量的应用形式为
unfold
,把从右向左变换的过程称为
fold
。
System
Type Parameters
我们使用一种新语法来表示类型的参数:
id
函数
id A
,就可以得到
Universally Quantified Types
对应新的项:
id
为:
id X
都有类型
基础构成
语法
System
断言
对于
规则
相比
Appl2中的
Existentially Quantified Types
与universally quantified types相反,existentially quantified types表示存在某个类型可以满足等式。
关于pack和open,这篇文章的解释非常详细,推荐阅读。
子类型
子类型的定义很简单:如果A是B的子类型,则任何A中的元素都属于B,记为:
Contravariant & Covariant
逆变(contravariant)和协变(covariant)是与子类型密切相关。如果有函数类型
总是出现在第奇数个箭头左边的类型是函数类型的逆变。
子类型可以与