Я имел эту идею типобезопасного языка шаблонного, который будет использовать полиморфные варианты в качестве источника переменных типобезопасного, которые могут быть заменены текстом, например:Типобезопасного замена переменного шаблона
type 'a t = Var of 'a | Text of string | Join of 'a t * 'a t
let rec render ~vars = function
| Text source -> source
| Var label -> vars label
| Join (left, right) -> render left ~vars^render right ~vars
let result = render (Join (Var `Foo, Text "bar")) ~vars:(function `Foo -> "foo");;
let() = assert (result = "foobar")
Все в порядке: компилятор будет обеспечивать, чтобы вы не забыли переменную замещения, или что у вас нет опечатки в имени переменной - благодаря полиморфным вариантам.
Однако, я считаю, две проблемы:
Вы можете случайно поставить неиспользуемую переменную.
Если шаблон не содержит переменных, вы по-прежнему вынуждены поставлять
~vars
функцию, и только один, который будет работать будетfun _ -> ""
илиfun _ -> assert false
, которые compromizes типа-безопасности в случае, если шаблон когда-либо изменения.
Я ищу совет по вышеуказанным проблемам, но я также ценю любые применимые рекомендации по дизайну API.
Как насчет 'Var of 'a *' a -> string'? Это выглядит некрасиво, но вам нужно связать принтер с переменной. Мое решение здесь - связать их с конструктором типа. – objmagic
@nnarklrh не уверен, что я следую. Что это за '' a -> string' принтер? Можете ли вы привести пример? – Halst
Извините, моя ошибка. Это должно быть 'Var of 'a * string'. Затем вы пишете «Var (' Foo, Foo) ». Но это кажется слишком громоздким. – objmagic