我在OCaml中很新,所以现在使用现有代码对我来说非常复杂,但不幸的是我需要它。
我有一个声明如下的变量:
val var_of_string : (string, int) Hashtbl.t
我想获得一个元素并将其显示在一个函数中。
let rec string_of_id n = match DynArray.get id_to_fml n with
Lit -> (if n land 1 == 0 then
string_of_int (Hashtbl.find var_of_string string_of_int(n))
else
"-" ^ string_of_int (Hashtbl.find var_of_string string_of_int(n))
)
| And ids ->
(match ids with
[] -> "#true#"
| _ -> "(" ^ String.concat " & " (List.map string_of_id ids) ^ ")")
| Or ids ->
(match ids with
[] -> "#false#"
| _ -> "(" ^ String.concat " | " (List.map string_of_id ids) ^ ")")
| Dia (r, n) -> "<" ^ string_of_int r ^ ">" ^ string_of_id n
| Box (r, n) -> "[" ^ string_of_int r ^ "]" ^ string_of_id n
| True -> "true"
| False -> "false"
基本上,唯一重要的部分是:
Lit -> (if n land 1 == 0 then
string_of_int (Hashtbl.find var_of_string string_of_int(n))
else
"-" ^ string_of_int (Hashtbl.find var_of_string string_of_int(n))
)
我有一个整数n
(可以成为string
)并且我有一个哈希表string ; int
。我希望能够在Hashtable的第n个案例中获取元素,但我不知道如何执行此操作:/
我通过查看documentation尝试Hashtbl.find var_of_string n
,但收到此错误消息:
Error: The implementation syntax.ml does not match the interface syntax.cmi:
Values do not match:
val var_of_string : (int, string) Hashtbl.t
is not included in
val var_of_string : (string, int) Hashtbl.t
File "syntax.ml", line 55, characters 4-17: Actual declaration
看起来我以错误的方式做某事,但我不知道该怎么做:/
提前感谢您的帮助!
答案 0 :(得分:3)
使用(==)
进行整数比较是一个坏习惯。请改用结构比较(=)
。 (==)
是使用指针的物理比较。对于整数,它们是相同的,但通常它们的行为不同。不小心使用(==)
会在一天内严重击中你的脚。
val var_of_string : (string, int) Hashtbl.t
是一个表格,其密钥为string
。您可以使用int
键添加/替换/删除/查找string
值。在您的代码中,您做了相反的事情:尝试使用string
键查找int
值。这是错误的。如果要从其ID号中查询变量的名称,则需要一个表string_of_var
,类型为(int, string) Hashtbl.t
。
一种可能的方法是从var_of_string
构建此反向表。通过使用var_of_string
在Hashtbl.iter
中迭代绑定可以轻松完成。但是,如果您可以直接构建string_of_var
而不使用var_of_string
,那么代码清晰度和性能会更好。没有足够的背景,我们无法分辨出哪种方式最适合你。
答案 1 :(得分:1)
您的Hashtable键为字符串,值为整数。
Hashtable.find具有以下签名:
val find : ('a, 'b) t -> 'a -> 'b
请参阅http://caml.inria.fr/pub/docs/manual-ocaml/libref/Hashtbl.html
您正在尝试对值使用Hashtable.find。