我正在开发OCaml中的一些算法,这些算法需要一些部分是“可插拔的”,因此部分计算留给了特定的计算器。
举个例子,假设我有一个像这样的签名:
module type Algorithm = sig
val feed : float -> unit
val nth : int -> (float -> float)
end
两个不同的实现将是Alg1
和Alg2
。这个Algorithm
模块应该代表这两个实现的各种实现的接口。
现在我需要另一个组件,我们称之为Executor
,它将是通过其接口使用Alg1
或Alg2
的模块。
阅读仿函数似乎我需要一个带有Algorithm
的仿函数,并生成一个ConcreteExecutor
,其具有我需要的算法的特定实现。因此Executor
是一种在其中一个组件上进行参数化的模块。
我是对的吗?这是获得我需要的最佳方式吗?我想这些想法是因为我来自Java / C ++背景所以我习惯使用接口和抽象类,我需要以正确的方式进入这个functor / module抽象问题。
获取我想要的东西的正确语法是什么?
提前致谢
答案 0 :(得分:4)
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。