.tex类型文件怎么阅读_类型系统简介

0f99010718306f6a877f274ed21fe7ff.png

类型系统是编程语言的重要组成部分,本文是对

type system​lucacardelli.name

的阅读笔记和梗概,强烈推荐感兴趣的同学阅读文章本身。

前置知识

类型系统的目的

类型系统(type system)的基本目标是防止程序在运行时发生类型错误。当且仅当语言运行时不存在任何形式的类型错误,那么它就是sound的。soundness是类型系统研究的重要目标。

对类型系统的描述

描述类型系统使用的是一种符号系统,它来自于自然推演(Natural Deduction)。有如下几个组成部分:

Judgments

Judgement是一条断言,一般具有如下形式:

表示
已知的事实
表示
推导出
表示
推导的结果,类型断言一般用来表示变量具有指定类型。例如:

表示在类型环境

中,自由变量M具有类型A。

有一条常用的通用断言:

表示类型环境

形式良好(well formed)的

还有一种语义:

,这表示了已知环境
加上一个本地环境
,可以推导出e。

Type rules

类型规则通过一条或多条断言来决定一条断言的正确性,一般有如下形式:

横线上方是一条或多条判断,描述了规则的前提(premise)。下方只能有一个判断,描述了规则的结论(conclusion)。顶部可以标注规则的名称和注释。前提的右边也可以写一些注释。

我们来举个例子:

这个例子认为在一个行为良好的类型环境中,所有的自然数都有类型Nat,两个类型同为Nat的表达式M和N相加的结果也为一个自然数。

有一条基本规则:空的环境是类型良好的,不需要任何假设:

一系列类型规则组成的集合称为一个正式的类型系统。

Type derivations

类型导出(Type derivations)在一个给定的类型系统中,是一颗树,它的底部的根节点和顶部的叶节点都是类型断言,且每条断言都可以由它上方的断言结合类型系统的规则直接获得。给定一个类型断言,我们可以将它放置在类型导出的根部(底部),利用类型规则一步一步向上推导,如果能够顺利推出,说明断言是合法的。

例如根据我们此前的规则,可以判断

是否合法:

Type inference

给定一个项M,如果它在类型环境

中是
良型的(well typed),那么存在一个类型A可以赋给M。通过类型导出为M确定A,称为 类型推导(Type inference)

System

基础构成

语法

一阶类型化的

演算(first-order typed
-calculus)被称作System
。我们可以给
演算添加类型注释,它的语法如下:

断言

对于

我们只需要三条简单的断言:

规则

有了这三条断言,我们可以写出它的类型规则:

基础类型

我们有了System

的基础骨架后,就可以给它增加一些基础类型。

Unit Type

Unit Type很常见,在很多语言中它又叫VoidNull

Bool Type

Bool Type也很常见,它是布尔值的类型,它一般拥有一个有用的操作,即通常语言中的if else语句,我们在这里称为cond:

在Cond中我们需要通过下标A来告诉类型检查器,结果应该是类型A,来消除潜在的类型检查困难。

Nat Type

Nat Type就是自然数的类型。假设我们有0和Succ,则1为Succ 0,2为Succ Succ 0。Nat还存在两种计算:predisZero,前者用来得到当前自然数前一位的自然数,后者用来判断自然数是否为0.

结构类型

Product Types

Product Types是一对类型,由两个类型构成,例如

就是一个product type。这两个类型可以通过
firstsecond操作符来提取出来。通过 with语句,我们可以把product type解构为两个单独的变量
,应用在作用域N中。

Union Types

Union Types指的是结合类型。例如一个union type

可以认为是一个带有left标记的类型为
的元素或带有right的类型为
的元素。这一标记可以由
isLeftisRight来进行测试,相应的类型可以由 asLeftasRight来提取。和之前Bool Type的Cond语句类似, asLeftasRight也需要下标来帮助类型检查器进行判断。

如果asRight被错误的应用在了由isLeft标记的元素上,那么我们就得到了一个被捕获的异常,这个异常不属于forbidden error。因此有了union Type,我们可以定义一个典型的被捕获的错误类型:

我们可以用它来表示任何类型的异常。

Record Types

Record Types是product types的升级版,它由product types迭代而来。对于record M中的每个组成变量

,都有名称
和它绑定。与product types相似,record types也有with语句。Product types
在record types中可以定义为

Variant Types

与recotd types和product的关系类似,variant types也由union types迭代而来。Union types

在variant types中可以被定义为

Reference Types

引用类型在命令式语言中很常见,它用来包裹地址可变的元素。可以由ref分配,由assign更新,并由deref解除。

Recursive Types

递归类型需要为环境中扩展一个类型变量X。类型变量的应用形式为

。例如有一个树类型
,我们可以将等式写为
,如果存在
不是
,且有唯一解使等式成立的情况。那么我们将这个解写为
。我们通过方式表示这个recursive type。由于在这里
,那么等式
是成立的。我们把从左向右变换的操作称为
unfold,把从右向左变换的过程称为 fold

System

Type Parameters

我们使用一种新语法来表示类型的参数:

,表示程序M中有类型变量X,例如对于
id函数
就可以被写为带有类型变量的:
,将类型A代入X,写为
id A,就可以得到

Universally Quantified Types

对应新的项:

,我们有新的
universally quantified types,前式可写为
,表示对于所有的X,程序体M都有类型A。例如上文中的
id为:
,表示对于所有的X,
id X都有类型

基础构成

语法

System

的类型如下,由于我们有了类型参数,所以System
中的基础类型K被去掉了。

断言

对于

,断言和
完全相同:

规则

相比

的类型环境添加了类型变量X。

Appl2中的

是指用B替换A中出现的X。

Existentially Quantified Types

与universally quantified types相反,existentially quantified types表示存在某个类型可以满足等式。

关于pack和open,这篇文章的解释非常详细,推荐阅读。

子类型

子类型的定义很简单:如果A是B的子类型,则任何A中的元素都属于B,记为:

。带有子类型的系统的断言如下:

Contravariant & Covariant

逆变(contravariant)和协变(covariant)是与子类型密切相关。如果有函数类型

,前者是后者的子类型。那么A一定接受任何A',所以A'是A的子类型,而产生的B一定属于任何B',那么B是B'的子类型。可以看出参数的子类型方向变化和函数整体是相反的,所以A是逆变的。而返回结果则是一致的,所以B是协变的。

总是出现在第奇数个箭头左边的类型是函数类型的逆变。

子类型可以与

结合,没有难以理解的部分,推荐阅读原文 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值