我可以只为某些仿函数参数定义一个 OCaml 函数吗?

Can I define an OCaml function only for certain functor parameters?

我想做这样的事情:

module Make (M: MInt) (N: MInt) : T = struct
    (* always defined *)
    let foo = 42

    (* only defined when M == N or M.x == N.x, something like that *)
    let bar a b = a * b
end

这可能吗?

显然我可以在运行时检查,但我很好奇如何在编译时进行检查。谢谢!

不,我认为仿函数的结果模块的(签名的)字段列表不可能以这种方式依赖于参数模块。我认为您可以获得的唯一一种依赖是类型替换。

要对此类事物进行编码,需要一种具有 dependent typing. Dependent typing is a powerful feature of a type system, but, unfortunately it complicates a language and makes type inference undecidable. Usually, this is much more, than average programmer would be ready to pay. If you really want a language that will allow you to write such specifications, then you need to try Coq 的语言。

OCaml 仍然支持通过 Generalized Algebraic Data types 在一定程度上限制依赖类型。因此,理论上,在 OCaml 中,您可以对一个函数进行编码,该类型确保两个参数是相等的整数。为此,您需要使用 Peano 数字而不是内置整数,或者用幻影类型注释内置整数,描述其大小。但所有这些都是不切实际的。在 Coq 中编写这个,然后将定义提取为 OCaml 程序要容易得多。

总而言之,不可能在仿函数级别上做您想做的事。可以使用 OCaml 类型系统来表达这样的东西。但最好为此使用 Coq,并在 OCaml 中保持简单。

您可以有第二个仿函数来扩展第一个仿函数,但要求模块相等:

module Make (M: MInt) (N: MInt) : T = struct
    let foo = 42
end

module Make2 (M: MInt) : T2 = struct
    include Make(M)(M)

    let bar a b = a * b
end