将多个OCaml签名归于模块

Gre*_*bet 4 ocaml module functor

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
Run Code Online (Sandbox Code Playgroud)

我想制作一个带有两个Ordered Fields并生成另一个的仿函数Ordered Field(假设操作是按组件方式应用的,我们使用字典顺序进行比较).如何指定"输入模块"同时满足两个签名?

这是我想要做的一些草编语法:

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

可能的情况是,有一种优雅的方式来获取签名的"联合"(但不是匿名联合),或者创建一个围绕具体ORDEREDFIELD实现的包装器模块,恰好碰巧共享类型t.我很好奇OCall的惯用方法是做我想要实现的目标.

cam*_*ter 8

使用include和定义新模块类型with type t := t:

module type ORDERED_FILED = sig
  include ORDERED
  include FIELD with type t := t
end
Run Code Online (Sandbox Code Playgroud)

没有with type t := t,因为两者的定义将被拒绝ORDERED,并FIELD声明了同名的类型.include FIELD with type t := t是"替代" tFIELD通过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
Run Code Online (Sandbox Code Playgroud)