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)
可能的情况是,有一种优雅的方式来获取签名的"联合"(但不是匿名联合),或者创建一个围绕具体ORDERED和FIELD实现的包装器模块,恰好碰巧共享类型t.我很好奇OCall的惯用方法是做我想要实现的目标.
使用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是"替代" t的FIELD通过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)