Проблема заключается в отсутствии круглых скобок вокруг fact n
:
let () = Printf.printf "%d factorial is %d.\n" n (fact n)
работает.
Причиной возникновения сложной ошибки типа является то, что компилятор читает
let () = Printf.printf "%d factorial is %d.\n" n fact(n)
as
let () = Printf.printf "%d factorial is %d.\n" n fact n
Другими словами, для компилятора функция printf
применяется к 4 аргументам: "%d factorial is %d.\n"
, n
, fact
и n
.
Но строка формата, назовем ее fmt
, содержит только два спецификатора %d
.Таким образом, компилятор также знает, что printf fmt
должен принять два аргумента и затем вернуть единицу.Существует несоответствие: ожидается, что Printf.printf fmt n fact
вернет функцию, которая может быть применена к последнему аргументу n
, но вернет единицу.Или, другими словами,
Тип 'a ->' b не совместим с типом unit
Предыдущая часть ошибки
Это выражение имеет тип ('a ->' b, out_channel, unit, unit, unit, 'a ->' b) CamlinternalFormatBasics.fmt, но ожидалось выражение типа ('a ->' b, out_channel, unit,единица измерения, единица измерения, единица измерения) CamlinternalFormatBasics.fmt
обусловлена тем, что тип строки форматирования является очень гибким, и поэтому проверка типов завершается неудачно только тогда, когда обнаруживается, что невозможно распечататьстрока формата и возвращает единицу с предоставленными аргументами.