如何让 ocaml 相信两个函子实例化是相等的

Ale*_* B. 2 ocaml

假设我有许多模块,它们都使用一种模块类型进行参数化,并且彼此之间也具有依赖关系:

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
Run Code Online (Sandbox Code Playgroud)

在这里,一切都用 参数化AT。那么 和CD独立的,并且E依赖于CD。此代码无法编译,因为编译器不相信内部E,C.HashtblD.Hashtbl是同一模块:

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
Run Code Online (Sandbox Code Playgroud)

有没有一种快速方法可以让 ocaml 相信两个哈希集模块是相同的?

oct*_*ron 5

类型检查器是正确的,这两个Hashtbl模块不相同,不应混合在一起:例如考虑一个稍微修改过的B模块:

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
Run Code Online (Sandbox Code Playgroud)

那么函子应用程序的两个实例C.B和不共享相同的盐。因此,混合源自 和 的哈希表将是一个错误,会导致完全不稳定的行为。D.BF(A)C.B.HashD.B.Hash