OCaml Hashtbl/0.t 和 Hashtbl/-1.t
OCaml Hashtbl/0.t and Hashtbl/-1.t
我对 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
显然,这只是缺少半列的问题,以下代码可以编译:
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
但是,我也不知道如何解释错误信息。
让我们举个例子:
如果我写
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
因此解释器试图告诉您这些类型都被命名为 t
但不一样。
[编译]
如果我想编译它,我必须声明
typea.ml
type t = A
let x = A
typeb.ml
type t = B
let y = B
main.ml
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
的定义(一个在 Core_kernel.Std
中,一个在标准库中)并且 OCaml 不是傻瓜,男孩,他知道你什么时候错了,但他很难理解,因为他只为那些能听到的人说话。 :-D
P.S。 : 你的 Hashtbl.find
中有一个错误,因为它没有 return 一个选项,而是找到的值,或者如果没有找到值则引发 Not_found
异常。我也纠正了它。 ;-)
我对 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
显然,这只是缺少半列的问题,以下代码可以编译:
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
但是,我也不知道如何解释错误信息。
让我们举个例子:
如果我写
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
因此解释器试图告诉您这些类型都被命名为 t
但不一样。
[编译]
如果我想编译它,我必须声明
typea.ml
type t = A
let x = A
typeb.ml
type t = B
let y = B
main.ml
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
的定义(一个在 Core_kernel.Std
中,一个在标准库中)并且 OCaml 不是傻瓜,男孩,他知道你什么时候错了,但他很难理解,因为他只为那些能听到的人说话。 :-D
P.S。 : 你的 Hashtbl.find
中有一个错误,因为它没有 return 一个选项,而是找到的值,或者如果没有找到值则引发 Not_found
异常。我也纠正了它。 ;-)