使用OCaml模块进行钻石继承

时间:2018-05-24 11:10:06

标签: ocaml

我有四个模块。

Ring,Field是Ring的子模块,Coefficient是Ring的子模块,Coefficientdivisible是Ring和Coefficicent的子模块。

module type Ring = 
sig
  type t
  val add : t -> t -> t
  multiply : t -> t -> t
  val zero : t
  val one : t   
  val opposite : t                      (* a+ opposite a =0*)
end

module type Field =
sig
  include Ring
  val division : t -> t-> t
end

module type Coefficient = 
sig
  include Ring
  val stringDeCoef : t -> string
end

module type Coefficientvisible = 
sig
  include Field
  include Coefficient
end

当我尝试编译前三个模块时,它没有问题,但第四个模块返回错误信息,ocamlc说:

  

文件“CoefficientDivisible.ml”,第7行,字符1-20:       错误:类型名称t的多个定义。          名称在给定结构或签名中必须是唯一的。

你有解决方案吗?

1 个答案:

答案 0 :(得分:4)

破坏性替换通常是多种定义困境的答案:

module type CoefficientDivisible = sig
   include Field
   include Coefficient with type t := t
end

另一种选择是使用较小的扩展模块类型并将它们组合在一起 显式生成基本模块类型的扩展版本。例如, 使用以下扩展模块类型:

module type RingToField = sig
   type t
   val division: t -> t -> t
end

module type RingToCoefficient = 
sig
    type t
    val stringOfCoef : t -> string
end

模块类型RingFieldCoefficientDivisible具有严格的定义:

module type Field = sig
  include Ring
  include RingToField with type t := t
end 

module type Coefficient = sig
  include Ring
  include RingToCoefficient with type t := t
end

module type CoefficientDivisible = sig
  include Field
  include RingToCoefficient with type t := t
end