Он применяется к слишком многим аргументам;может быть, вы забыли `; ' - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь написать код, который вычисляет размер списка.

Вот что я сделал:

let rec l = function 
  | [] -> 0 
  | t::q -> 1 + l q


print_int(l ([1;2;3;4]))

Проблема в том, что он говорит мне:

It is applied to too many arguments; maybe you forgot a `;'.

Когда я ставлю двойную точку с запятой ;; в конце определения l, это работает хорошо, но я читал, что ;; вообще бесполезен, если вы не кодируетев REPL, поэтому здесь я не понимаю, почему он дает мне эту ошибку.

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

При синтаксическом анализе кода анализатор продвигается, пока не достигнет l q.На этом этапе может быть больше аргументов, которые следует применить к функции l.Таким образом, анализатор продолжает работать, и следующая вещь, которую он находит, это значение print_int.Еще один аргумент в пользу л.Что дает вам вашу ошибку.

Парсер не может знать, что вы закончили код для функции l.На верхнем уровне специальный токен ;; используется, чтобы сообщить синтаксическому анализатору, что ввод завершен, и теперь он должен оценить код.После этого он снова начинает обрабатывать оставшиеся входные данные.

Теперь, почему скомпилированный код также не имеет ';;'токен?

Просто потому, что он не нужен.В скомпилированном коде строка print_int(l [1;2;3;4]) не является допустимым вводом.Это было бы утверждение, которое вы хотите выполнить, и функциональные языки не имеют такой вещи.Вместо этого print_int(l [1;2;3;4]) - это выражение, которое возвращает значение () в этом случае, и вы должны указать компилятору, что делать с этим значением.let () = говорит компилятору сопоставить его с ().И let ... также сообщает компилятору, что предыдущий let rec l ... завершен.Поэтому никакого специального токена ;; не требуется.

Или подумайте об этом так: на верхнем уровне есть неявный let _ =, если ваш ввод не начинается с let.Таким образом, вы можете просто ввести какое-нибудь выражение и посмотреть, к чему оно относится, без необходимости каждый раз вводить let _ =.';;'токен все еще означает «оценить сейчас», хотя и все еще необходим.

0 голосов
/ 11 июня 2018

Следующее

print_int(l [1;2;3;4])

является выражением верхнего уровня.Такому выражению должен предшествовать ;;:

;; print_int(l [1;2;3;4])

Другой вариант - сделать это выражение верхнего уровня связыванием с

let () = print_int(l [1;2;3;4])
...