我是否可以仅为某些函子参数定义OCaml函数?

时间:2015-08-09 08:53:08

标签: ocaml

我想做这样的事情:

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

这可能吗?

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

3 个答案:

答案 0 :(得分:1)

要编码此类内容,需要使用dependent typing的语言。依赖类型是类型系统的一个强大功能,但不幸的是它使语言复杂化并使类型推断变得不可判定。通常,这比普通程序员准备支付的要多得多。如果您真的想要一种允许您编写此类规范的语言,那么您需要尝试Coq

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

总而言之,在仿函数级别上不可能做到你想要的。使用OCaml类型系统来表达这样的事情是可能的。但是最好使用Coq,并在OCaml中保持简单。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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