将哈希表标识为OCaml中的用户定义类型

kra*_*ash 9 ocaml types

我希望能够定义一个类型(比如my_type),它可以将字符串作为键标识为哈希表并映射到整数值.
所以,我试过了

# type my_type = (string, int) Hashtbl.t;;
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试

# let a = Hashtbl.create 100;;
val a : ('_a, '_b) Hashtbl.t = <abstr>
# Hashtbl.add a "A" 12;;
- : unit = ()
# a;;
- : (string, int) Hashtbl.t = <abstr>
Run Code Online (Sandbox Code Playgroud)

最后一行显示(string,int)Hashtbl.t = abstr而不是my_type.我如何确保它将哈希表的类型作为my_type?

gas*_*che 9

声明类型同义词并期望编译器在精确的情况下使用一个表达式或另一个表达式是没有意义的:因为它们是相同的类型,编译器将使用任何一个并且您几乎无法控制它.

如果要强制执行类型抽象,以便不将类型my_type与任何其他类型混合(string, int) Hashtbl.t,则应该使用构造函数来定义一个标记差异的新类型:

type my_type = Tbl of (string, int) Hashtbl.t
let a = Tbl (Hashtbl.create 100)
let add (Tbl t) k v = Hashtbl.add t k v
Run Code Online (Sandbox Code Playgroud)

您可能想要这样(并且my_type当您想要使用其中一个Hashtbl函数时,需要支付通过显式模式匹配将所有值转换为哈希表的成本),或者您可能只想操纵类型同义词,但在后一种情况下您不应期望编译器输出报告任何特定类型.


jro*_*uie 1

my_type只是 的同义词(string, int) Hashtbl.t,您可以互换使用两者。

您可以告诉编译器a类型为my_type,并获得更好的输出,如下所示:

# let (a:my_type) = Hashtbl.create 100;;
val a : my_type = <abstr>
# a;;
- : my_type = <abstr>
Run Code Online (Sandbox Code Playgroud)

如果您想知道<abstr>,这意味着顶层不知道如何打印a(它的内容,而不是它的类型)。