将多个 OCaml 签名分配给一个模块

Ascribing multiple OCaml Signatures to a Module

Ocaml 组合签名

假设我有两个签名,Ordered 和 Field

module type ORDERED = sig 
    type t
    type comparison = LT | EQ | GT
    val cmp : t -> t -> comparison
end

module type FIELD = sig
    type t
    val (+) : t -> t -> t
    val ( * ) : t -> t -> t
    val inv : t -> t
    val neg : t -> t
    val zero : t
    val one : t
end

我想制作一个仿函数,它接受两个 Ordered Fields 并产生另一个 Ordered Field(假设操作是按组件应用的,我们使用字典顺序进行比较)。我如何指定 "input modules" 同时满足两个签名?

这是我想做的一些稻草人语法:

module NaivePair = functor (Left : ORDERED & FIELD) (Right : ORDERED & FIELD) ->
    struct
        type t = Left.t * Right.t
        (* definitions *)
    end

可能有一种优雅的方式来获取 "union" 签名(但不是匿名联合),或者围绕具体的 ORDERED 和 [=15= 创建包装器模块] 恰好共享类型 t 的实现。我很好奇惯用的 OCaml 方法是什么来完成我想要实现的目标。

使用 includewith type t := t 定义新模块类型:

module type ORDERED_FIELD = sig
  include ORDERED
  include FIELD with type t := t
end

如果没有 with type t := t,定义将被拒绝,因为 ORDEREDFIELD 都声明了相同名称的类型。 include FIELD with type t := t 是将 FIELDt 替换为 ORDERED.t

ocamlc -i -c x.ml看看ORDERED_FIELD是你想要的:

$ ocamlc -i -c x.ml
...
...
module type ORDERED_FILED =
  sig
    type t
    type comparison = LT | EQ | GT
    val cmp : t -> t -> comparison
    val ( + ) : t -> t -> t
    val ( * ) : t -> t -> t
    val inv : t -> t
    val neg : t -> t
    val zero : t
    val one : t
  end