讓我們告訴你一個例子:
如果我寫
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
中發生錯誤,因爲如果未找到任何值,它將不會返回選項,而會返回找到的值或引發Not_found
異常。我也糾正了它。 ;-)
我確定你使用的是解釋器,請參閱我的答案;-) – Lhooq