Programming languages 类型化递归模块

Programming languages 类型化递归模块,programming-languages,module,functional-programming,ocaml,strong-typing,Programming Languages,Module,Functional Programming,Ocaml,Strong Typing,在《关于如何在OCaml中键入递归模块》一书中,写到在由模块类型近似值构成的环境中检查模块: module rec A = ... and B = ... and C = ... 首先构建环境{A->approx(A);B->approx(B);C->approx(C)},然后用于计算A、B和C的类型 我注意到,在某些情况下,近似值不够好,并且类型检查失败。特别是,当将编译单元源放在递归模块定义中时,类型检查可能会失败,而编译器能够单独编译编译单元 回到我的第一个示例,我发现一个解决方案是在初

在《关于如何在OCaml中键入递归模块》一书中,写到在由模块类型近似值构成的环境中检查模块:

module rec A = ... and B = ... and C = ...
首先构建环境{A->approx(A);B->approx(B);C->approx(C)},然后用于计算A、B和C的类型

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

回到我的第一个示例,我发现一个解决方案是在初始近似环境中使用类型a,然后在初始环境中使用新的计算类型a扩展类型B,在以前的环境中使用新的计算类型B扩展类型C,依此类推

在进一步研究之前,我想知道在这个主题上是否有任何先前的工作,表明递归模块的这种编译方案是安全的还是不安全的?是否有反例显示使用此方案正确键入的不安全程序?

首先,请注意,Leroy(或Ocaml)不允许没有明确签名注释的
模块rec
。所以它相当

module rec A : SA = ... and B : SB = ... and C : SC = ...
近似环境是{A:approx(SA),B:approx(SB),C:approx(SC)}

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

关于您的建议,它的问题在于它使
模块rec
构造不对称,即顺序可能以微妙的方式影响。这违反了递归定义的精神(至少在ML中是这样),递归定义应该总是对顺序漠不关心

一般来说,递归类型的问题不在于可靠性,而在于完整性。您不希望类型系统通常是不可判定的,或者其规范依赖于算法人工制品(如检查顺序)


更一般地说,众所周知,Ocaml对递归模块的处理相当严格。有一些工作,例如中田佳理(Nakata&Garrigue)的工作,进一步推动了其极限。然而,我确信,如果不放弃Ocaml纯语法的模块类型方法,最终您将无法获得您想要的自由(这也适用于其类型模块系统的其他方面,例如函子)。但是,我有偏见。:)

确实是一个非常有趣的问题。请注意,您提出的解决方案忽略了A的类型可能依赖于B和C的类型,如果不是这样,则没有理由将它们一起进行类型检查(与依赖顺序相反)。不,实际上,A的类型可以依赖于B和C,但我假设在这种情况下,B和C的近似值就足够了。我的问题来自一个真实的例子,我用这个解决方案在编译器中编写了一个补丁来解决这个问题,程序是安全的(因为它由具有递归类型的编译单元组成),但我想知道在一般情况下补丁是否安全。感谢指向Nakata&Garrigue工作的指针,我不知道它。诚然,顺序对于
let rec
,并不重要,但在语言的其他部分,它确实重要。
let x=x+2 in let x=x*3 in…
取决于顺序。那么,为什么不在顺序很重要的地方引入一个
模块incremental rec
,并允许键入现在无法键入的程序呢?(现在,我必须读一下报纸…)嗯,嵌套的
let
是不可比较的。您可以将其与并行的
进行比较,将x=a和y=b放在…
中,实际上,顺序对于键入并不重要。为什么没有增量记录?嗯,依我看,那将是一个丑陋的黑客行为,而且它只涉及一些特定的用例你不想要一个更通用的解决方案吗?我想要一个更通用的解决方案,但是当没有解决方案时(我仍然需要阅读更多关于递归模块的内容…),我对一个粗糙的解决方案很满意。我不认为这是针对“一些特定的用例”,我认为我的问题可能会经常出现。值得指出的是,这个响应的作者编写了MixML(),这可以说是处理递归的ML中模块系统的最新技术。