使用functor作为OCaml中的接口

时间:2010-08-05 15:16:16

标签: interface ocaml functor

我正在开发OCaml中的一些算法,这些算法需要一些部分是“可插拔的”,因此部分计算留给了特定的计算器。

举个例子,假设我有一个像这样的签名:

module type Algorithm = sig
    val feed : float -> unit
    val nth : int -> (float -> float)
end

两个不同的实现将是Alg1Alg2。这个Algorithm模块应该代表这两个实现的各种实现的接口。

现在我需要另一个组件,我们称之为Executor,它将是通过其接口使用Alg1Alg2的模块。

阅读仿函数似乎我需要一个带有Algorithm的仿函数,并生成一个ConcreteExecutor,其具有我需要的算法的特定实现。因此Executor是一种在其中一个组件上进行参数化的模块。

我是对的吗?这是获得我需要的最佳方式吗?我想这些想法是因为我来自Java / C ++背景所以我习惯使用接口和抽象类,我需要以正确的方式进入这个functor / module抽象问题。

获取我想要的东西的正确语法是什么?

提前致谢

1 个答案:

答案 0 :(得分:4)

是的,这听起来像算子是你想要的。实际上,您可以查看标准库如何使用仿函数,因为源代码可用。在我的机器上,它位于/usr/lib/ocaml/3.10.2/。例如,set.mli包含以下内容:

module type OrderedType =
  sig
    type t
    val compare : t -> t -> int
  end

module type S
  sig
    ...
  end

module Make (Ord : OrderedType) : S with type elt = Ord.t

如果你想在OCaml中使用一个集合,你可以:

module SSet = Set.Make(String);;

因此,使用您的代码,Algorithm替换OrderedType,Alg1 / Alg2替换String,Executor替换Make,而ConcreteExecutor是Executor(Alg1 / Alg2)的结果。您还会注意到string.mli / ml不包含OrderedType的任何提及。 String是OrderedType,因为它具有由函数compare使用的类型t。您不需要明确说明String是OrderedType。