Нельзя использовать обратные знаки в именах терминов, поскольку обратные знаки используются camlp5 (OCaml)

#ocaml #camlp4

#ocaml #camlp4

Вопрос:

Я использую библиотеку Yojson, и один из используемых конструкторов называется `Bool (с обратным знаком). Я работаю с исходным кодом OCaml, где используется camlp5, так что текст, окруженный обратными знаками, интерпретируется по-разному (например, текст преобразуется в структуру данных OCaml).

Проблема, с которой я сталкиваюсь, заключается в том, что когда `Bool появляется в моем исходном коде, camlp5 / OCaml видит обратную ссылку и думает, что это начало цитаты, вызывая ошибку. Как я могу убедиться, что это интерпретируется как термин `Bool OCaml вместо этого? Есть ли какой-нибудь способ временно отключить то, что делает campl5? Какой-то escape-символ, который я могу использовать?

Комментарии:

1. `Bool — это стандартная нотация OCaml для полиморфного варианта, и Camlp5 поддерживает это должным образом. Ваша проблема, должно быть, в чем-то другом.

2. Спасибо. Есть какие-либо намеки на то, что это может быть? Мой код отлично работает при новом запуске OCaml. Когда я загружаю код для проекта, который я использую, обозначение `Bool перестает работать. Проект допускает использование текста, заключенного в кавычки, для специальных обозначений. Я предположил, что это было через Camlp5.

3. maltbar, приведи какой-нибудь минимально воспроизводимый пример, иначе нам будет трудно угадать решение. Мое предположение — какое-то расширение синтаксиса нарушено.

Ответ №1:

Поскольку вы используете расширение синтаксиса, которое переопределяет поведение обратных кавычек, вы не можете использовать полиморфные варианты, такие как `Bool в том же файле.

Я бы посоветовал вам сначала изменить расширение синтаксиса, чтобы использовать символ, отличный от обратных кавычек. Почему бы и нет, %% например?

Другое решение простое, но более подробное: используйте два разных файла, в одном из которых вы не используете расширение синтаксиса, а в другом — где вы используете расширение синтаксиса.

В первом файле (без расширения синтаксиса) вы определяете тип с обычными вариантами, которые похожи на те, которые используются в Yojson, и функции для перевода из и в полиморфные варианты:

 type t = 
 | Bool of ...
 | ...

let to_yojson x = 
  match x with
   | Bool v -> `Bool v
   | ...

let from_yojson x =
  match x with
   | `Bool v -> Bool v
   | ...
  

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