我对OCaml很新,所以我不确定以下错误消息的含义(特别是/0
和/-1
):
Error: This expression has type (string, string) Hashtbl/0.t
but an expression was expected of type ('a, 'b) Hashtbl/-1.t
我正在将Hashtbl.t
传递给Hashtbl.find
,此错误会显示出来。我不清楚/0
和/-1
是如何进入的,以及它们实际意味着什么。
以下是演示我的问题的最小工作示例:
open Core_kernel.Std
let file_to_hashtbl filename =
let sexp_to_hashtbl_str = Sexplib.Conv.hashtbl_of_sexp
string_of_sexp string_of_sexp
in In_channel.with_file
filename ~f:(fun ch -> (Sexp.input_sexp ch |> sexp_to_hashtbl_str))
let ht = file_to_hashtbl "test"
let t1_val = match Hashtbl.find ht "t1" with
| Some v -> v
| None -> assert false
let () = print_endline t1_val
答案 0 :(得分:2)
让我们举个例子:
如果我写
type t = A;;
let x = A;;
type t = B;;
let y = B;;
x = y;;
Error: This expression has type t/1561 but an expression was expected of type
t/1558
这是因为在解释器中,您可以声明具有相同名称的多个类型,并将值与这些类型相关联。但是在这里,正如您所看到的,x
和y
的类型不同,但两种类型都被命名为t
,因此解释器会尝试告诉您类型都被命名为{{ 1}}但不一样。
[编译]
如果我想编译它,我必须声明
<强> typea.ml 强>
t
<强> typeb.ml 强>
type t = A
let x = A
<强> main.ml 强>
type t = B
let y = B
如果我编译它,我将
open Typea
open Typeb
x = y
你应该从中吸取什么教训? 停止解释,编译!
既然我设法编译了你的文件,我也得到了一个错误,但更加明确:
Error: This expression has type Typeb.t
but an expression was expected of type Typea.t
[解释和更正]
由于我太好了,这里更正了你的文件:
Error: This expression has type (string, string) Hashtbl.t
but an expression was expected of type
('a, 'b) Core_kernel.Std.Hashtbl.t =
('a, 'b) Core_kernel.Core_hashtbl.t
您的错误是您将let file_to_hashtbl filename =
(* open the namespace only where needed *)
let open Core_kernel.Std in
let sexp_to_hashtbl_str = Sexplib.Conv.hashtbl_of_sexp
string_of_sexp string_of_sexp
in In_channel.with_file
filename ~f:(fun ch -> (Sexp.input_sexp ch |> sexp_to_hashtbl_str));;
let ht = file_to_hashtbl "test"
let t1_val =
try
Hashtbl.find ht "t1"
with Not_found -> assert false
let () = print_endline t1_val
打开为全局命名空间,因此当您编写Core_kernel.Std
时,它首先在Hashtbl.find
中查找,而不是在标准库中。
我所做的是在需要它的函数中打开Core_kernel.Std
,而不是在整个文件中打开(因此它是一个本地命名空间)(采取的好习惯)。
所以,正如您所看到的,问题在于您有两种类型Core_kernel.Std
的定义(一个在Hashtbl.t
中,一个在标准库中)而OCaml没有傻瓜,男孩,他知道你什么时候出错,但他很难理解,因为他只会说那些能听到的人。 :-D
P.S。 :您的Core_kernel.Std
出现错误,因为它没有返回选项但会找到找到的值,或者如果找不到值则引发Hashtbl.find
例外。我也纠正了它。 ; - )
答案 1 :(得分:-1)
显然,这只是缺少半列的问题,下面的代码编译:
open Core_kernel.Std;;
let file_to_hashtbl filename =
let sexp_to_hashtbl_str = Sexplib.Conv.hashtbl_of_sexp
string_of_sexp string_of_sexp
in In_channel.with_file
filename ~f:(fun ch -> (Sexp.input_sexp ch |> sexp_to_hashtbl_str));;
let ht = file_to_hashtbl "test"
let t1_val = match Hashtbl.find ht "t1" with
| Some v -> v
| None -> assert false
let () = print_endline t1_val
但是,我不知道如何解释错误信息。