在Ocaml中设计2个交互式模块

时间:2011-11-13 17:13:58

标签: module ocaml

我想设计2个模块AB,它们都有自己的功能,例如:A.compare: A.t -> A.t -> boolB.compare: B.t -> B.t -> boolAB的元素是可转换的。所以我还需要函数a_of_b : B.t -> A.tb_of_a : A.t -> B.t。我的问题是我应该在哪里定义这些功能?在AB或其他地方的结构内部?

有人可以帮忙吗?

Edit1:刚刚修改了一些基于第一条评论的错误

2 个答案:

答案 0 :(得分:1)

您可能意味着A.compare: A.t -> A.t -> bool因为类型较小。

您可以拥有一个单独的模块AB,其中包含A的类型和B的类型。

您可以拥有包含A& A的单个模块AB。 B作为子模块。

您也可以使用recursive modules&函子。

答案 1 :(得分:1)

这是一个经典的设计问题。在OOP语言中,很难优雅地解决这个问题,因为类封装了类型定义和与该类型相关的方法。因此,只要你有一个像a_of_b这样的函数,它将两种类型视为相同的范围,就没有明确的位置。

OCaml正确地为这些不同的需求提供了不同的语言机制:使用关键字type引入类型定义,并在module中收集相关方法。这为您设计API提供了更大的灵活性,但并未自动解决问题。

一种可能性是定义模块A和B,两者都有各自的类型和比较功能。然后,剩下的问题是放置a_of_bb_of_a的位置。您可以任意优先考虑模块A,并定义函数A.to_bA.of_b。这就是标准库在将to_listof_list放入Array时所执行的操作。这缺乏对称性;没有理由不将这些功能放在B中。

相反,您可以使用of_函数与to_函数进行标准化。假设你更喜欢to_。然后,您将定义函数A.to_bB.to_a。现在的问题是模块A和B是相互依赖的,只有在同一个文件中定义它们才能实现。

如果您将有许多处理类型A.tB.t的值的函数,那么可能值得定义模块AB,并将所有这些函数放在那里。如果你只需要两个,那么额外的模块可能有点过分。

另一方面,如果关于A和B的函数总数很小,则只能使用type atype b以及所有相关方法创建模块AB。但是,这并不遵循OCaml社区在其自己的模块中命名类型t的惯例,并且将Set和Map仿函数应用于这些类型将更加困难。