Почему локальное отключение предупреждения о частичном приложении не работает - PullRequest
0 голосов
/ 15 февраля 2019

В OCaml 4.08 новое предупреждение о частичных приложениях выводится по умолчанию, например:

let _ = (Format.printf "side-effect!@."; List.iter (fun () -> ()))
2 |   (Format.printf "side-effect!@."; List.iter (fun () -> ()))
                                       ^^^^^^^^^^^^^^^^^^^^^^^^
Warning 5: this function application is partial,
maybe some arguments are missing.

Попытка отключить его локально, добавив аннотации везде, похоже, не работает:

let[@warning "-5"] _ [@warning "-5"] =
  (Format.printf "side-effect!@."; List.iter (fun () -> ()))[@@warning "-5"]

Единственный способ, который работает, - это использовать технику [@@@warning "-5"] в качестве , упомянутого здесь .Однако в этом вопросе упоминается, что

Локальное отключение предупреждений с помощью [@warning "…"] и [@@ warning "…"] недостаточно поддерживается для версий OCaml, предшествующих 4.06.0 * 1014.*

Каким должен быть в этом случае синтаксис для OCaml 4.08, чтобы локально отключать такие предупреждения?

Редактировать : в соответствии с предложением glennsl, заменив let _ = ... наignore (...) предлагает альтернативу (добавление [@@warning "-5"] после того, как ignore (...), кажется, работает), но она менее однородна, поскольку объявления верхнего уровня не могут быть заменены таким образом, хотя их можно безопасно окружить [@@@warning "-5"]/[@@@warning "+5"] 1 .Тем не менее, это не объясняет, почему моя первая попытка не сработала: она написана неправильно, это из-за дизайна или, возможно, из-за недосмотра?

1 Этот «взлом» такжеимеет недостаток, заключающийся в возможности изменения предыдущего состояния;например, если предупреждение 5 ранее было отключено на глобальном уровне, это может привести к его непреднамеренному повторному включению.

1 Ответ

0 голосов
/ 15 февраля 2019

Я бы сказал, что следующая цитата из прекрасного руководства (раздел 8.13.1) указывает на то, что ответ "по (отсутствию) конструкции":

Обратите внимание, что это не очень хорошоопределил, какая область используется для конкретного предупреждения.Это зависит от реализации и может меняться между версиями.

Теперь, если мы пытаемся интерпретировать, почему ваши попытки заставить замолчать предупреждение не сработали, мы можем проверить, о чем предупреждение 5:

выражение, результат которого имеет тип функции и игнорируется.

Таким образом, предупреждение выдается, когда у нас есть функциональное выражение e в определенном контексте.В случае ignore контекст - это просто приложение, то есть захватывающее выражение, а область, в которой мы можем попросить забыть о предупреждении 5, должна быть примерно самим выражением ignore (и его выражениями и элементом захвата).

Теперь для let _ = ... все не так ясно: e игнорируется, когда он привязан к шаблону универсального охвата _.Можно утверждать, что размещение [@@ warning "-5"] в конце let-привязки должно охватывать все определение, но, как упоминалось выше, компилятор совершенно свободен не соглашаться с этой интерпретацией.

Однако это дает альтернативуРешение, которое вообще не должно отключать предупреждение 5: просто свяжите выражение с переменной (конечно, начиная с _, чтобы избежать предупреждения 26):

let _i_swear_to_hb_curry_i_know_what_i_m_doing =
  Format.printf "side-effect!@."; List.iter (fun () -> ());;

не вызывает никакого предупреждения:будучи привязанным к такой переменной, выражение может все еще казаться немного пренебреженным, но оно не может жаловаться, что активно игнорируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...