Давайте покажем вам пример:
Если я пишу
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