在OCaml中键入共享 - 类型检查错误

KCH*_*KCH 3 ocaml functional-programming module functor

编译此程序时:

module type Inc =
    sig
        type t
        val inc : t -> t
    end

module type Dec = 
    sig
        type t
        val dec : t -> t
    end

module Merger (I : Inc) (D : Dec with type t = I.t) =
    struct
        let merge x = x |> I.inc |> D.dec
    end

module IntInc : Inc = 
    struct
        type t = int
        let inc x = x + 10
    end

module IntDec : Dec = 
    struct 
        type t = int
        let dec x = x - 8
    end

module Combiner = Merger (IntInc) (IntDec)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

File "simple.ml", line 30, characters 35-41:
Error: Signature mismatch:
       Modules do not match:
         sig type t = IntDec.t val dec : t -> t end
       is not included in
         sig type t = IntInc.t val dec : t -> t end
       Type declarations do not match:
         type t = IntDec.t
       is not included in
         type t = IntInc.t
       File "simple.ml", line 13, characters 38-50: Expected declaration
       File "simple.ml", line 9, characters 13-14: Actual declaration
Run Code Online (Sandbox Code Playgroud)

我认为这种D : Dec with type t = I.t约束将确保这一点D.t = I.t.为什么不是这样?

更有趣的是,当我删除module Combiner = Merger (IntInc) (IntDec)它时,它编译没有错误.

我的问题是:我做错了什么?

sep*_*p2k 6

Merger对约束的定义是完全正确的,这就是为什么该部分编译没有错误.

正如你所说,唯一没有编译的部分是module Combiner = Merger (IntInc) (IntDec).这是因为,就OCaml所知,IntInt.t = IntDec.t不满足约束条件.其原因是,OCaml的不知道IntInt.tIntDec.tint.所有它知道的是- IntInt : Inc并且IntDec : Dec- 其他一切都是模块的私有细节.

要解决这个问题,你可以改变模块的标头IntInt : (Inc with type t = int)IntDec : (Dec with type t = int),使得式t模块的公共接口的一部分,而不是私人的细节,让OCaml中来解决的约束时使用该信息Merger函子.