У меня есть очень простая логика в OCaml:
let load filename =
let file = get_file filename in
let len = String.length file in
Printf.printf "%a\n" file
()
(get_file
- это функция, которую я написал.) Как вы можете видеть из этого фрагмента, я хочу напечатать содержимое file
просто чтобы понять, что он возвращает. Я использовал %a
, потому что в одном из учебных пособий по OCaml сказано, что вы должны делать это для такого рода вещей. Когда я говорю «такого рода вещи», я имею в виду канал, и для этого я покажу, как выглядит моя get_file
функция:
let get_file filename =
let channel = open_in_bin filename in
let length = in_channel_length channel in
let file = really_input_string channel length in
close_in channel;
file
Хорошо, так что ссылаясь на мой код в load
метод, я получаю следующую ошибку:
6 | Printf.printf "%a\n" file
^^^^
Error: This expression has type string but an expression was expected of type
out_channel -> 'a -> unit
Так что я думаю: «Хорошо, это строка типа - так как это то, что говорится в сообщении - поэтому я должен сделать это в моем printf». Поэтому я изменяю свой printf следующим образом:
Printf.printf "%s\n" file
И все же теперь ошибка:
6 | Printf.printf "%s\n" file
^^^^^^
Error: This expression has type
('a -> 'b, out_channel, unit, unit, unit, 'a -> 'b)
CamlinternalFormatBasics.fmt
but an expression was expected of type
('a -> 'b, out_channel, unit, unit, unit, unit)
CamlinternalFormatBasics.fmt
Type 'a -> 'b is not compatible with type unit
Я понятия не имею, как вы должны сделать что-то из этого тупого сообщения об ошибке,учитывая сообщение об ошибке, с которого я изначально начинал, когда использовал %a
.
Итак, я подумал, что, возможно, file
было неправильной попыткой, так как это канал, и, возможно, я что-то упустил. Поэтому вместо этого я пытаюсь распечатать переменную len
, которая должна быть просто целым числом. Я изменяю свой printf следующим образом:
Printf.printf "%d\n" len
И получаю еще одно бесполезное (для меня) сообщение об ошибке:
6 | Printf.printf "%d\n" len
^^^^^^
Error: This expression has type
('a -> 'b, out_channel, unit, unit, unit, 'a -> 'b)
CamlinternalFormatBasics.fmt
but an expression was expected of type
('a -> 'b, out_channel, unit, unit, unit, unit)
CamlinternalFormatBasics.fmt
Type 'a -> 'b is not compatible with type unit
Я попытался переключить printf для len
на %a
просто чтобы посмотреть, что он сообщил, и я получил это:
6 | Printf.printf "%a\n" len
^^^
Error: This expression has type int but an expression was expected of type
out_channel -> 'a -> unit
Да, у него есть тип int. Это то, что я изначально пытался напечатать! Так что это зеркальная ситуация из первых. Одно сообщение об ошибке говорит мне, что переменная имеет определенный тип. Затем я пытаюсь напечатать этот конкретный тип, и получаю более длинное, но гораздо менее полезное (для меня) сообщение об ошибке.
Я не могу найти приличное руководство по OCaml, которое просто проведет вас через этот простой примериспользуя диагностические операторы печати, чтобы определить, что делает язык, поэтому публикуем здесь, чтобы узнать, что я делаю неправильно.