Type sharing in OCaml - typechecker error

江枫思渺然 提交于 2020-01-02 07:07:14

问题


When compiling this program:

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

I thought that D : Dec with type t = I.t constraint will ensure that D.t = I.t. Why it is not so?

What is more interesting, when I remove module Combiner = Merger (IntInc) (IntDec) line it compiles without errors.

My question is : What am I doing wrong?


回答1:


Your definition of Merger with the constraint is perfectly correct, which is why that part compiles without error.

As you said, the only part that doesn't compile is module Combiner = Merger (IntInc) (IntDec). This is because, as far as OCaml knows, the constraint IntInt.t = IntDec.t is not met. The reason for that is that OCaml does not know that IntInt.t and IntDec.t are int. All it knows is that IntInt : Inc and IntDec : Dec - everything else is a private detail of the module.

To fix this problem you can change the module's headers to IntInt : (Inc with type t = int) and IntDec : (Dec with type t = int), making the type t a part of the modules' public interface rather than a private detail, allowing OCaml to use that information when resolving the constraint of the Merger functor.



来源:https://stackoverflow.com/questions/27295630/type-sharing-in-ocaml-typechecker-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!