从OCaml中的Hashtbl获取一个元素

时间:2015-12-16 09:32:21

标签: ocaml hashtable

我在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

看起来我以错误的方式做某事,但我不知道该怎么做:/

提前感谢您的帮助!

2 个答案:

答案 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_stringHashtbl.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。