How to convince ocaml that two functor instantiations are equal

情到浓时终转凉″ 提交于 2019-12-24 10:53:49

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/48693701/how-to-convince-ocaml-that-two-functor-instantiations-are-equal

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