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

如何使ocaml确信两个函子实例化是相等的,ocaml,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

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

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
在这里,所有内容都通过
AT
参数化。然后,
C
D
是独立的,
E
依赖于
C
D
。由于编译器不确信在
E
中,
C.Hashtbl
D.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

有没有一种快速的方法来说服OCAML,这两个哈什特模块是相同的?< /P> < P>类型检查器是正确的,这两个代码> Hashtbl < /Cult>模块是不相同的,不应该混合在一起:考虑例如稍微修改的<代码> 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

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

在阅读了更多内容后,我认为您错了。Ocaml函子应该是可应用的,typechecker应该认为该函子对同一模块的应用是相同的,即使模块由于副作用捕获了不同的值。关于这一点,我提出了一个单独的问题: