编程语言 – 键入递归模块

Leroy’s paper中,关于如何在OCaml中输入递归模块,写入模块在由模块类型的近似组成的环境中进行检查:

module rec A = ... and B = ... and C = ...

环境{A – >约(A); B – >约(B); C – >约(C)}首先构建,然后用于计算A,B和C的类型.

我注意到,在某些情况下,近似值不够好,类型检查失败.特别地,当将编译单元的源放在递归模块定义中时,类型检查可能会失败,而编译器能够单独编译编译单元.

回到我的第一个例子,我发现一个解决方案是在初始近似环境中键入A,然后在新的计算类型的A中扩展的初始环境中键入B,并在以前的env中键入C,新的计算类型的B,等等.

在进行更多调查之前,我想知道是否有任何关于这个问题的工作,表明这种递归模块的编译方案是安全的还是不安全的?有没有一个反例,显示一个不安全的程序正确输入这个方案?

首先,请注意,Leroy(或Ocaml)不允许没有显式签名注释的模块记录.所以是这样的

module rec A : SA = ... and B : SB = ... and C : SC = ...

近似环境为{A:约(SA),B:约(SB),C:约(SC)}.

一些模块在单独定义时进行类型检查,但不是递归定义时,这并不奇怪.毕竟,对于核心语言声明来说也是如此:在“let rec”中,绑定变量的递归出现是单形式的,而使用分离的“let”声明,可以多个使用以前的变量.直观地,原因在于,在实际检查定义之前,您不可能拥有所有知识,您需要推断更自由的类型.

关于你的建议,它的问题在于它使得模块被构造成不对称,即顺序将以潜在的微妙方式起作用.这违反了递归定义的精神(至少在ML中),这应该总是对订单无动于衷.

一般来说,递归打字的问题不是那么健全,而是完整.您不想要一般不认可的类型系统,或者其规范取决于算法伪影(如检查顺序).

在更一般的注意事项中,众所周知,Ocaml对递归模块的处理是相当有限的.已经有工作,例如由Nakata&加力,进一步推动其极限.然而,我相信,最终,你将无法像你想要的那样自由(这也适用于其类型模块系统的其他方面,例如函子),而不会放弃Ocaml纯粹的句法方法进行模块打字.但是,我有偏见. 🙂

翻译自:https://stackoverflow.com/questions/9375953/typing-recursive-modules

转载注明原文:编程语言 – 键入递归模块