Type sharing in OCaml - typechecker error

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 = It) = 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 the D : Dec with type t = It constraint ensures that Dt = It . Why is this not so?

More interestingly, when I delete the line module Combiner = Merger (IntInc) (IntDec) , it compiles without errors.

My question is: what am I doing wrong?

+3
source share
1 answer

Your restriction definition of Merger is perfectly correct, so this part compiles without errors.

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

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

+5
source

Source: https://habr.com/ru/post/1232821/


All Articles