TL类型语言的可选组合器参数及其值
TL 语言允许将组合器的前几个参数声明为可选参数。因此,这些参数几乎不需要显式声明。这与 TL 的另一个重要特性——多态性——直接相关,所有可选参数通常都必须是结果类型的一部分(至少一次)。(子)表达式可以通过以下两种方式之一进行序列化/反序列化:
-
结果类型是已知的(例如,我们正在解析先前发送的 RPC 查询的响应,因此知道预期值的类型)。在这种情况下,结果类型可用于确定组合器的隐式参数的值。
-
结果类型未知。它取决于序列化(反序列化)的结果(例如,我们正在序列化 RPC 查询)。在这种情况下,必须使用组合器的完整版本来显式指定(并序列化)组合器的所有可选参数。
我们将假设函数组合器与构造器的区别仅在于,在其结果类型之前!隐式地添加了修饰符,并且函数表达式的(远程或本地)计算可以表示为执行某些多态函数eval : !X -> X。
此外,未知结果类型显然通常(但不总是)与表达式的序列化有关,该表达式的类型已被修改!。
我们可以制定以下规则。设存在某个构造函数。
C {a1:T1} ... {am:Tm} b1:U1 ... bn:Un = T;
它的一些参数或结果可能带有修饰符!(我们认为函数组合器是一个构造器,其结果类型已被隐式修改!)。
必须满足以下条件:
-
每种类型T1、…、Tm、U1、…、Un和T都可能依赖于类型为Type或 的参数#,这些参数已在使用给定类型的左侧声明。
-
隐式参数T1、…、Tm的类型不能被修改!。
-
只允许使用类型为Type`T` 或 ` C` 的隐式参数#。换句话说,`Ti`要么是 `T`,Type要么是 `C` #。(与之前的规则不同,这条规则将来可能会放宽。)
-
每个隐式参数a1 , ..., am必须至少使用一次——要么在具有 a 的Ui!类型之一中,要么在结果类型T中,如果它没有显式或隐式参数!。
-
如果结果类型中未使用隐式参数ai ,或者结果类型具有 ,则其首次(最左侧)使用必须在由 修改的!类型Uj!内。
其思路如下:我们假设在对某个类型被修改的值进行序列化/反序列化时,!我们事先并不知道该值的类型,只能根据序列化/反序列化的结果来确定其类型;反之,我们假设在对某个类型未被修改的值进行序列化/反序列化时,!我们事先知道该值的类型。在这种情况下,遵循上述规则可以确保我们始终能够计算出所有隐式参数的值——无论是基于(先前已知的)结果类型,还是基于某个参数的类型bj:!Uj(该参数是在序列化过程中获得的)。
实际上,!`--type` 表示类型信息的流动方向。默认情况下,结果类型是类型(及其参数)信息的来源,而参数类型是信息的接收者。使用 `--type`!会反转信息流的方向,使结果类型成为类型信息的接收者,而参数类型成为类型信息的来源。
另请参阅二进制序列化和抽象 TL 类型以及TL 中的多态性。