Возможно ли воспроизвести интерполяцию строк python в ocaml?

В python можно использовать форматирование printf с помощью оператора "%":

"i am %d years old" % 99

или

"%s is %d years old" % ("bob", 101)

Есть ли способ получить такой же краткий синтаксис в Ocaml, для произвольного количества аргументов?

Для одного аргумента выполняется следующее:

let (%) = Printf.sprintf in ... "i am %d years old" % 99

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

Ответ 1

В теории, не представляется более трудным использовать формат для создания типа (typ1 * typ2 * ... * typn) -> string, чем typ1 -> typ2 -> ... -> typn -> string. То есть, возможно, за исключением рекурсивных форматов %( fmt %). Кто-нибудь действительно использует их?

На практике, однако, разработчики OCaml выбрали последнюю форму и реализовали типы системных хаков для этой формы, а не для первой. Поэтому я боюсь, что ответ заключается в том, что, не исправляя компилятор, вы застряли в curried форме замены строки формата.

Ответ 2

Это зависит от того, что вы подразумеваете под произвольным числом аргументов:

  • Я не верю, что есть способ написать функцию в OCaml, которая может принимать и распаковывать кортеж произвольной арности (например, как (1, "bob"), так и ("joe", "bob", "briggs")).

  • Режим Caml для обработки нескольких аргументов - это не кортежи, а каррирование. Если вы захотите это сделать, вы можете просто использовать Printf.sprintf.

  • Если вам действительно нужен инфиксный оператор, например, что-то вроде

    "%s-%s %s is the best movie reviewer" % "joe" "bob" "briggs"
    

    тогда вам не повезло, потому что приложение функции привязывается сильнее, чем любой оператор infix. Вы можете написать

    ("%s-%s %s is the best movie reviewer" % "joe") "bob" "briggs"
    

    но для меня это похоже на точку, а не на дроидов, которые вы ищете.

Итак, если ваш вопрос:

Могу ли я определить в Objective Caml инфиксную версию sprintf, которая принимает произвольное количество аргументов?

Ответ нет.

Ответ 3

Это похоже на работу для Camlp4!

Ответ 4

Вы можете сделать это с помощью префикса op, а не infix:

let (!%) = Printf.sprintf

Если вам нужен только сжатый способ написания sprintf, этого достаточно.

Как сказал Тобу, вам нужен P4, если вы хотите, чтобы Python был особым синтаксисом. Я считаю, что это слишком сложно.