How to convince ocaml that two functor instantiati

2019-08-02 15:14发布

Suppose I have a number of modules that are all parameterized with one module type, and also have dependencies between each other:

module type AT = sig  
end

module B(A: AT) = struct
  module Hash = struct
    type t = int
    let equal b1 b2 = b1 = b2
    let hash b = b
  end
end

module C(A: AT) = struct
  module B = B(A)
  module Hashtbl = Hashtbl.Make(B.Hash)

  let make () = Hashtbl.create 16
end

module D(A: AT) = struct
  module B = B(A)
  module Hashtbl = Hashtbl.Make(B.Hash)

  let use ht =
    Hashtbl.clear ht
end

module E(A: AT) = struct
  module C = C(A)
  module D = D(A)

  let f () =
    D.use (C.make ())
end

Here, everything is parameterized with AT. Then, C and D are independent, and E depends on C and D. This code does not compile, since the compiler is not convinced that inside E, C.Hashtbl and D.Hashtbl are the same module:

File "xxxx.ml", line xx, characters xx-xx:
Error: This expression has type 'a C.Hashtbl.t = 'a Hashtbl.Make(C.B.Hash).t
       but an expression was expected of type
         'b D.Hashtbl.t = 'b Hashtbl.Make(D.B.Hash).t

Is there a quick way to convince ocaml that the two hashset modules are the same?

标签: ocaml
1条回答
放我归山
2楼-- · 2019-08-02 15:33

The typechecker is right that the two Hashtbl modules are not the same and should not be mixed together: consider for instance a slightly modified B module:

module B(A: AT) = struct
  module Hash = struct
    let y = Random.int 10
    type t = int
    let equal b1 b2 = b1 = b2
    let hash b = b + y
  end
end

Then the two instances C.B and D.B of the functor application F(A) do not share the same salt. Consequently, mixing hash tables derived from C.B.Hash and D.B.Hash would be an error that leads to a completely erratic behavior.

查看更多
登录 后发表回答