所以我想写一个函数,以一个第一类模块作为参数,在Base.Map和Base.Hashtbl上工作,但我遇到了一个问题。这段代码说明了发生了什么。
module type Len_intf = sig
type t
val length : t -> int
end
let show (type a) (module L : Len_intf with type t = a) h =
printf "len: %d\n" @@ L.length h
let test (type a) h =
show (module Hashtbl : Len_intf with type t = a) h
试图编译的结果是:
Error: Signature mismatch:
...
Type declarations do not match:
type ('a, 'b) t = ('a, 'b) Poly.t
is not included in
type t
They have different arities.
File "test.ml", line 2, characters 2-8:
Expected declaration
File "src/hashtbl_intf.ml", line 552, characters 2-17:
Actual declaration
由于Hashtbl和Map的类型arity不同,这可能吗?
编写一个接受一级模块的函数当然是可以的(你这样做了),而且可以这样调用。
let test (type a) (type b) h =
let module M = struct
type t = (a,b) Hashtbl.t
let length = Hashtbl.length
end in
show (module M) h
但我认为不可能按照你的方式来做。事实上,除了签名已经描述的内容之外,类型等价还在后面。它们不能防止类型性不匹配。