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

5

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(假设对操作进行分量应用并使用字典顺序进行比较)。我该如何指定“输入模块”同时满足两个签名?

以下是一些草稿语法,适用于我要完成的任务:

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

可能有一种优雅的方法可以将签名(但不是匿名联合)"联合"起来,或者创建一个包装器模块,围绕具体的ORDEREDFIELD实现,它们恰好共享一个类型t。 我很好奇我所尝试实现的OCaml习惯用法是什么。

1个回答

9

使用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是将FIELD中的tORDERED.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

模块类型可以是一等公民吗? - Olle Härstedt
你会如何使用这个函数对象?@erwaman,能否提供一个例子?感谢分享。 - armand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接