如何使用一些默认实现在OCaml中实现模块签名?

如何使用一些默认实现在OCaml中实现模块签名?,ocaml,Ocaml,我想在OCaml中实现一个模块签名,如下所示,其中函数get_data取决于每个模块实现并返回一个选项类型。我还想提供函数get_data_exn,它通过取消选择get_data的结果来包装get_数据,并在get_data返回的结果为None时引发异常 本质上,函数get_data_exn的实现如下所示,对于实现Foo的所有模块都是相同的: 我是否可以在签名Foo中包含get_data_exn的这个实现,这样我就不必在其他模块中重复它了?这类似于Java中的抽象类 谢谢你花时间考虑我的问题。

我想在OCaml中实现一个模块签名,如下所示,其中函数get_data取决于每个模块实现并返回一个选项类型。我还想提供函数get_data_exn,它通过取消选择get_data的结果来包装get_数据,并在get_data返回的结果为None时引发异常

本质上,函数get_data_exn的实现如下所示,对于实现Foo的所有模块都是相同的:

我是否可以在签名Foo中包含get_data_exn的这个实现,这样我就不必在其他模块中重复它了?这类似于Java中的抽象类


谢谢你花时间考虑我的问题。

你可以定义一个核心模块类型

module type Foo_core = sig
  type t
  val get_data: int -> t option
end
并使用函子对其进行扩展:

module Get_data_exn(Core:Foo_core) = struct
  let get_data_exn value = match Core.get_data value with
  | Some data -> data
  | None -> raise DataNotFound
end
根据您的用例,公开标准Make_foo函子可能会很有用


您可以定义核心模块类型

module type Foo_core = sig
  type t
  val get_data: int -> t option
end
并使用函子对其进行扩展:

module Get_data_exn(Core:Foo_core) = struct
  let get_data_exn value = match Core.get_data value with
  | Some data -> data
  | None -> raise DataNotFound
end
根据您的用例,公开标准Make_foo函子可能会很有用


谢谢你的建议。我理解你的想法,尽管模块系统变得更复杂了。您认为是否有更简单的解决方案?@TrungTa在OCaml中,让代码声明可见并可跟踪到阅读代码的人是非常重要的。因此,无法在模块中隐式声明。虽然一开始它们很吓人,但函子是一个很棒的工具,你应该学会使用它。@Trung Ta,有一个更复杂的类和虚拟方法的解决方案,但是模块系统本身在设计上非常明确。@PatJ,octachron:谢谢你的澄清。谢谢你的建议。我理解你的想法,尽管模块系统变得更复杂了。您认为是否有更简单的解决方案?@TrungTa在OCaml中,让代码声明可见并可跟踪到阅读代码的人是非常重要的。因此,无法在模块中隐式声明。虽然一开始它们很吓人,但函子是一个很棒的工具,你应该学会使用它。@Trung-Ta,有一个更复杂的解决方案,包含类和虚拟方法,但是模块系统本身在设计上非常明确。@PatJ,octachron:谢谢你的澄清。
module Make_full_Foo(X:Foo_core) = struct
  include X
  include Get_data_exn(X)
end