Skip to content

关系参数性

Relational parametricity · Reynolds parametricity · Abstraction theorem

多态项必须统一保持类型之间任意关系的抽象定理及其行为约束。

形式陈述

在纯、总的 System F 中,关系环境 η 为每个类型变量 α 指定两个闭类型 A1,A2 及其值之间的关系 Rα。这是一种按类型递归的二元逻辑关系。变量和箭头分支为

V[[α]]η=Rα,V[[AB]]η={(f1,f2)(a1,a2)V[[A]]η,(f1a1,f2a2)E[[B]]η}.

全称类型要求保持每一种可选关系:

(v1,v2)V[[α.A]]η当且仅当B1,B2,RVal(B1)×Val(B2),(v1[B1],v2[B2])E[[A]]η[α(B1,B2,R)].

关系参数性或 abstraction theorem 是逻辑关系基本定理在这套解释上的实例:若 Γe:A,则对相关的类型实例化和项环境,两份实例化后的 eE[[A]] 下相关。闭合多态项因此与自身跨任意类型关系相关。这里的“自身”仍包含左右两侧不同的类型实例,不是逐字复制后得到的平凡等式。

参数多态是一种类型系统能力;关系参数性是关于该语言全部良类型项的元定理。重载或 ad-hoc polymorphism 可以按类型选择不同实现,不满足上述“任意关系都保持”的前提,不能只因语法里有泛型参数就套用本定理。

直觉

一个对未知 α 工作的程序没有类型专属的观察手段。若输入元素在某个任意关系下配对,它只能通过类型允许的统一结构搬运、丢弃或组合这些元素,不能突然识别“左边是整数、右边是字符串”。把“不了解表示”精确化为“保持所有关系”,便从类型签名得到强行为约束。

关系环境比只比较相同类型更有力。它可以把编码不同、值集合不同的两个类型联系起来;多态程序若仍保持该关系,就说明其行为不依赖任何一侧的具体表示。

例子与边界

f:α.αα。任取类型 A 与值 a:A,再选择只把某个辅助值与 a 配对的关系;参数性迫使 f[A]a 仍与该辅助值对应,因此在纯、总、无类型反射的语义中,f 只能观察等价于恒等函数的行为。这个结论依赖总性:若允许发散,f 还可能永不返回。

g:α.List(α)N,逐元素关系会把形状相同的两条列表配对,而完全不限制相关元素的具体表示。参数性于是要求 g 对这两条列表返回同一自然数;它可以依赖空/非空、长度等列表形状,却不能检查元素是零、字符串还是某个对象身份。

底值、异常、引用、指针相等、类型反射、不安全转换以及 Haskell 风格 seq 都会改变可观察行为或允许程序探查本应抽象的信息。相应语言可能仍有经过 admissibility、world、step index 或部分性修正的参数性定理,但不能无条件沿用经典 Reynolds 版本。

推论与应用

关系参数性支撑表示隐藏、程序等式和从多态类型导出的自然性条件。所谓 free theorem 是进一步选择特定关系并把关系结论化为程序等式的应用;推导时仍要写明总性、纯度和观察等价,不能把“代码复用”当成形式证明。

编译器若做类型擦除或多态优化,也可用参数性说明程序不能观察被擦除的类型信息。不过当源语言暴露运行时类型表示或字典参数时,证明必须把这些额外值纳入关系,而不是假定所有泛型语言都与纯 System F 相同。

参考资料
  • John C. Reynolds, “Types, Abstraction and Parametric Polymorphism,” in Information Processing 83, 1983。
  • Philip Wadler, “Theorems for Free!” FPCA, 1989。
  • Robert Harper, Practical Foundations for Programming Languages, 2nd ed., Cambridge University Press, 2016,parametricity and abstraction。