| 類型系統 |
| --- |
| 
一般概念 |
| * 类型安全
* 强类型与弱类型
 |
| 
主要分类 |
| * 静态类型与动态类型
* 明示类型（英语：）与推论类型
* 名称类型（英语：）与结构类型（英语：）
* 鸭子类型
 |
| 
次要分类 |
| * 抽象类型
* 依赖类型
* 流程敏感类型（英语：）
* 渐进类型（英语：）
* 交集类型（英语：）
* 潜在类型（英语：）
* 细化类型（英语：）
* 子结构类型（英语：）
* 唯一类型（英语：）
* 会话类型（英语：）
 |
| * 
* 论
* 编
 |

在计算机科学和逻辑中，**依赖类型**（或**依存类型**，**dependent type**）是指依赖于值的类型，其理论同时包含了数学基础中的类型论和计算机编程中用以减少程序错误的类型系统两方面。在 Per Martin-Löf 的直觉类型论中，依赖类型可对应于谓词逻辑中的全称量词和存在量词；在依赖类型函数式编程语言如ATS（英语：）、Agda、Dependent ML（英语：）、Epigram（英语：）、F\*和Idris中，依赖类型系统通过极其丰富的类型表达能力使得程序规范得以借助类型的形式被检查，从而有效减少程序错误。

依赖类型的两个常见实例是**依赖函数类型**（又称**依赖乘积类型**、**Π-类型**）和**依赖值对类型**（又称**依赖总和类型**、**Σ-类型**）。一个依赖类型函数的返回值类型可以依赖于某个参数的具体值，而非仅仅参数的类型，例如，一个输入参数为整型值n的函数可能返回一个长度为n的数组；一个依赖类型值对中的第二个值可以依赖于第一个值，例如，依赖类型可表示这样的类型：它由一对整数组成，其中的第二个数总是大于第一个数。

依赖类型增加了类型系统的复杂度。由于确定两个依赖于值的类型的等价性需要涉及具体的计算，若允许在依赖类型中使用任意值的话，其类型检查将会成为不可判定问题；换言之，无法确保程序的类型检查一定会停机。

由于Curry-Howard同构揭示了程序语言的类型论与证明论的直觉逻辑之间的紧密关联性，以依赖类型系统为基础的编程语言大多同时也作为构造证明与可验证程序的辅助工具而存在，如 Coq 和 Agda（但并非所有证明辅助工具都以类型论为基础）；近年来，一些以通用和系统编程为目的的编程语言被设计出来，如 Idris。

一些以证明辅助为主要目的的编程语言采用强函数式编程（total functional programming），这消除了停机问题，同时也意味着通过它们自身的核心语言无法实现任意无限递归，不是图灵完全的，如 Coq 和 Agda；另外一些依赖类型编程语言则是图灵完全的，如 Idris、由 ML 衍生而来的 ATS 和 由 F# 衍生而来的 F\*。

形式化定义
-----

### Π-类型

在全类（论域中全部类型构成的类型） {\displaystyle {\mathcal {U}}} 中给定一个类型 {\displaystyle A:{\mathcal {U}}}，存在着**类型族** {\displaystyle B:A\to {\mathcal {U}}} 为每一项 {\displaystyle a:A} 赋予一个类型 {\displaystyle B(a):{\mathcal {U}}}。一个值域依赖于其参数的函数，称之为一个**依赖类型函数**，该函数的类型则称之为**依赖类型**、**依赖乘积类型**或**Π-类型**。在此例子中，依赖类型可以写作

{\displaystyle \Pi \_{(x:A)}B(x)}
或

{\displaystyle \Pi (x:A),B(x)}
若*B*为常数，则依赖类型退化成一般形态的函数 {\displaystyle A\to B}。即 {\displaystyle \Pi \_{(x:A)}B} 等价于函数类型 {\displaystyle A\to B}。

被称之为"Π-类型"的原因是它可以被看作是类型的笛卡尔积。Π-类型同时也可被看作是全称量词的模型。

例如，{\displaystyle {\mbox{Vec}}({\mathbb {R} },n)}表示实数的{\displaystyle n}-元组类型，则 {\displaystyle \Pi \_{(n:{\mathbb {N} })}{\mbox{Vec}}({\mathbb {R} },n)} 表示这样的函数类型：给定一个自然数*n*，该函数返回一个大小为n的实数元组。一般的函数空间可以看作依赖型函数的一个特例，当函数返回值类型实质上并不依赖于输入时，如 {\displaystyle \Pi \_{(n:{\mathbb {N} })}\;{\mathbb {R} }} 即为从自然数到实数的函数类型，它可以在简单类型lambda演算中被写作 {\displaystyle {\mathbb {N} }\to {\mathbb {R} }}。

多态是依赖类型函数的一个重要实例。给定一个类型，函数作用于该类型的元素之上。一个返回元素类型为*C*的多态函数可能拥有如下的多态类型：

{\displaystyle \Pi \_{(A:{\mathcal {U}})}A\to C}
### Σ-类型

依赖函数类型的对偶是**依赖值对类型**（或**依赖总和类型**、**Σ-类型**）。它与余积或不交并的概念相类似。Σ-类型可以被理解成存在量词的模型。写作：

{\displaystyle \Sigma \_{(x:A)}B(x)}
依赖值对类型表示一个值对，其中第二项的类型依赖于第一项的值。若

{\displaystyle (a,b):\Sigma \_{(x:A)}B(x)}
则 {\displaystyle a:A} 且 {\displaystyle b:B(a)}。若*B*为常数，则依赖值对类型退化为一般的乘积类型，即笛卡尔积 {\displaystyle A\times B}。

Lambda 立方
---------

Henk Barendregt 提出了 Lambda 立方模型，用于对不同的类型系统的表达能力加以区分。Lambda 立方的八个顶点分别对应各自的类型系统，简单类型lambda演算位于表达能力最低的顶点上，而构造演算（calculus of constructions）则位于表达能力最强的顶点上。

### 一阶依赖类型

一阶依赖类型 {\displaystyle \lambda \Pi }，对应于逻辑框架 LF，是通过把简单类型lambda演算的函数空间一般化为依赖乘积类型而获得的。

### 二阶依赖类型

二阶依赖类型 {\displaystyle \lambda \Pi 2}，通过允许对 {\displaystyle \lambda \Pi } 类型构造子的量化得到。此时，依赖乘积类型涵括了简单类型lambda演算中的{\displaystyle \to }与 系统F 中的{\displaystyle \forall }。

### 高阶依赖类型多态 lambda 演算

高阶类型系统 {\displaystyle \lambda \Pi \omega } 扩充了 {\displaystyle \lambda \Pi 2}，使之支持 Lambda 立方中的全部四种表达形式：从项到项的函数、从类型到类型的函数、从项到类型的函数、以及从类型到项的函数。这对应于构造演算（calculus of constructions），而构造演算则是证明辅助器 Coq 所基于的构造归纳演算理论的基础。

依赖类型编程语言
--------

| 语言 | 是否活跃开发中 | 范式 | 策略（tactics） | 证明项 | 终止检查 | 类型允许依赖于 | 全类 | 证明无关性 | 是否支持程序抽取 | 程序抽取是否消除无关项 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Agda | 是 | 纯函数式 | 少且有限 | 是 | 是（可选） | 任意项 | 是（可选） | 证明无关性参数 | Haskell、JavaScript | 是 |
| ATS（英语：） | 是 | 函数式 / 命令式 | 否 | 是 | 是 | ? | ? | ? | 是 | ? |
| Cayenne | 否 | 纯函数式 | 否 | 是 | 否 | 任意项 | 否 | 否 | ? | ? |
| Gallina（Coq） | 是 | 纯函数式 | 是 | 是 | 是 | 任意项 | 是 | 否 | Haskell、Scheme、OCaml | 是 |
| Dependent ML（英语：） | 否 | ? | ? | 是 | ? | 自然数 | ? | ? | ? | ? |
| Guru | 否 | 纯函数式 | hypjoin | 是 | 是 | 任意项 | 否 | 是 | Carraway | 是 |
| Idris | 是 | 纯函数式 | 是 | 是 | 是（可选） | 任意项 | 是 | 否 | 是 | 是 |
| Matita（英语：） | 是 | 纯函数式 | 是 | 是 | 是 | 任意项 | 是 | 是 | OCaml | 是 |
| Nuprl（英语：） | 是 | 纯函数式 | 是 | 是 | 是 | 任意项 | 是 | ? | 是 | ? |
| F\* | 是 | 函数式 / 命令式 | ? | ? | ? | ? | ? | ? | ? | ? |
| PVS（英语：） | 是 | ? | 是 | ? | ? | ? | ? | ? | ? | ? |
| Sage | ? | 混合类型检查 | ? | ? | ? | ? | ? | ? | ? | ? |
| Twelf（英语：） | 是 | 逻辑式 | ? | 是 | 是（可选） | 任意（LF）项 | 否 | 否 | ? | ? |

参见
--

* Lambda立方体
* 有类型lambda演算
* 直觉类型论

参考文献
----

1. ↑ .  [2019-04-12]. （原始内容存档于2020-11-11）.
2. ↑ .  [2014-08-24]. （原始内容存档于2019-06-27）.
3. ↑ .  [2014-08-24]. （原始内容存档于2009-04-17）.
4. 1 2 .  [2014-08-24]. （原始内容存档于2011-07-18）.
5. ↑ .  [2014-08-24]. （原始内容存档于2012-03-02）.
6. ↑ .  [2014-08-24]. （原始内容存档于2013-02-04）.
7. ↑  Augustsson, Lennart.. ICFP '98. Proceedings of the third ACM SIGPLAN international conference on Functional programming. 1998: 239–250. CiteSeerX 10.1.1.47.155 可免费查阅. S2CID 18331937. doi:10.1145/289423.289451 可免费查阅.
8. ↑ .  [2014-08-24]. （原始内容存档于2018-09-29）.
9. ↑  Guru （页面存档备份，存于）
10. ↑ .  [2014-08-24]. （原始内容存档于2015-11-18）.
11. 1 2  Aaron Stump.  (PDF). 6 April 2009  [28 September 2010]. （原始内容 (PDF)存档于2009年12月29日）.
12. ↑  Adam Petcher.  (PDF). 1 April 2008  [14 October 2010]. （原始内容存档 (PDF)于2010-07-19）.
13. ↑  . [永久]
14. ↑   (PDF).  [2014-08-24]. （原始内容 (PDF)存档于2011-07-16）.
15. 1 2  Edwin Brady. .
16. ↑ .  [2014-08-24]. （原始内容存档于2006-05-08）.
17. ↑  Sage （页面存档备份，存于）

延伸阅读
----

* Why Dependent Types Matter （页面存档备份，存于） T. Altenkirch, C. McBride, J. McKinna



|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
编程范型 |
| --- |
|  |
| 指令式 | 
* 过程式
* 非结构化
* 结构化
* 例外处理

 |
|  |
| 函数式 | 
* 纯函数式
* 全函数式
* 隐式
	+ 函数级
	+ 串接式

 |
|  |
| 面向对象 | 
* 基于类
* 基于原型
* 契约式
* 面向代理

 |
|  |
| 元编程 | 
* 
* 模板
* 反射式
	+ 同像性
	+ 元对象
	+ 元类
* 面向特性
* 面向语言

 |
|  |
| 数据流程 | 
* 同步式
* 响应式
	+ 函数式响应式
* 管道
* 串流处理
* 基于流程

 |
|  |
| 宣告式 | 
* 逻辑式
	+ 回答集
	+ 函数式逻辑
* 约束式
* 数据查询
* 框架本体

 |
|  |
| / | 
* 协程
* 通信顺序进程
	+ 通道
* 演员模型
* future/promise
* 分叉会合
* 整体同步

 |
|  |
| 其他 | 
* 阵列式
* 模块化
	+ 关注分离
* 面向方面
* 数据驱动
* 事件驱动
* 非确定性
* 面向堆栈
* 自动机
* 可微分
* 概率式

 |
|  |
|  有关概念 | 
* 块
* 递归
* 多态
	+ 运算符重载
	+ 泛型
	+ 多分派
* 头等对象
	+ 头等函数
	+ 闭包
* 实化
	+ 续体
* 求值策略
* 代数数据类型
* 模式匹配
* 推导式

 |
|  |
| 多范型语言比较（英语：） |

 |