9

我希望能够定义一种类型(比如 my_type),它可以识别以字符串为键的哈希表并映射到整数值。
所以,我尝试了

# type my_type = (string, int) Hashtbl.t;;

但是,当我尝试

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

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

4

3 回答 3

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

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

于 2013-03-10T15:05:51.383 回答
2

更新:抱歉,正如gasche指出的那样,您可以使用简单的类型注释来做到这一点,忘记类型强制

# type my_type = (string, int) Hashtbl.t;;
type my_type = (string, int) Hashtbl.t
# let (a : my_type) = Hashtbl.create 100;;
val a : my_type = <abstr>
于 2013-03-10T14:37:15.833 回答
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>

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

于 2013-03-10T13:57:39.307 回答