如何说服ocaml两个仿函数实例是相等的

时间:2018-02-08 19:52:19

标签: 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

此处,所有内容都使用AT进行参数化。然后,CD是独立的,E取决于CD。此代码无法编译,因为编译器不相信EC.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

有没有一种快速方法可以说服ocaml这两个hashset模块是相同的?

1 个答案:

答案 0 :(得分:3)

类型检查器是正确的,两个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

然后,仿函数应用程序C.B的两个实例D.BF(A)不共享相同的salt。因此,混合从C.B.HashD.B.Hash派生的哈希表将是一个导致完全不稳定行为的错误。