OCaml中的类型共享 - 类型检查器错误

3
编译此程序时:
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)

I get the following error:

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

我认为D: Dec with type t = I.t的约束条件会确保D.t = I.t。为什么这不是事实呢?

更有趣的是,当我删除module Combiner = Merger (IntInc) (IntDec)这一行时,它可以编译通过而没有错误。

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

1个回答

6

您对带有约束条件的Merger的定义是完全正确的,这就是为什么那部分可以编译通过的原因。

正如您所说,唯一无法编译的部分是module Combiner = Merger (IntInc) (IntDec)。这是因为,在OCaml看来,约束条件IntInt.t = IntDec.t没有得到满足。原因在于,OCaml不知道IntInt.tIntDec.tint类型。它只知道IntInt : IncIntDec : Dec——其他所有内容都是模块的私有细节。

要解决此问题,您可以将模块头更改为IntInt : (Inc with type t = int)IntDec : (Dec with type t = int),使类型t成为模块的公共接口而不是私有细节,从而允许OCaml在解析Merger函数器的约束时使用该信息。


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