子类型关系
安全替换原则
在TAT中,一个变量x
的类型若为{a: Num}
,你能够对它做的唯一特殊的操作,就是x.a
。
x.a
这个操作预期得到一个Num
类型的变量而不会发生运行时错误。
因此,若在一个期望类型为{a: Num}
的地方,传入一个要求更高的值{a: 1, b: 2}
,也完全符合"得到一个Num
类型而不会发生运行时错误"的预期。
那么,{a:1, b:2}
也就成为了一个合法的{a: Num}
。
我们把这种对替换的直觉,归纳成为子类型的安全替换原则。如下:
若我们可以将任何类型的值替换为类型的值而安全使用,那么我们称 是 的子类型,记做。
这里说的安全使用,可以理解成不产生运行时错误。
这里用的子类型关系记号<:
,其实也是在暗示这种关系是一种特殊的"大小关系"(用数学一点的说法来说,是一种序关系)。
你可以将它类比为集合的关系,或是数字的关系。
形式化子类型关系
我们在TAT的类型系统中,扩展一下定型规则,使其引入子类型。
这个规则的意思是说,若是的子类型,那么类型的项也是类型的项。
类型 和类型 的关系如下:
- 是 的子类型。
- 比 信息更丰富、要求更高。
例如,直觉上来看,类型 比类型 更严格、实例数量更少、要求更高。
若将类型看成一个集合,类型 是类型 的真子集。前者的所有元素都是后者的元素。
子类型关系
基于安全替换原则,我们可以形式化定义子类型关系的一些代数性质:
子类型的自反性。即,类型是自己的子类型。 ${S<:S} \tag{S-Refl} $
子类型的传递性。即,若,且,就有。