Возможно ли воспроизвести интерполяцию строк 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 был особым синтаксисом. Я считаю, что это слишком сложно.