Допустим, нам нужно написать сериализатор значений для XML-RPC. Спека определяет правила сериализации для примитивов. С этим проблем нет. Заводим трейт
CanRepresentAs[-From, +To]
где определяем метод
Далее для каждого примитивного типа заводим по implicit занчению типа CanRepresentAs[XXX, scala.xml.Node] с нужной реализацией. Эти значения затем подтягиваются в качестве implicit-параметров в те функции, которые нуждаются в сериализации. С примитивами разобрались, переходим к массивам и структурам. Массив тоже сериализуется очень просто, мы определяем implicit-функцию
implicit def seqAsXML[T](implicit sr: CanRepresentAs[T, scala.xml.Node]): CanRepresentAs[Seq[T], scala.xml.Node]
и дальше всё происходит по той же схеме. А вот со структурами дело обстоит сложнее ввиду их разнородности. Мы не можем представить структуру как Map, потому что её поля имеют разный тип. Логично было бы определить правила сериализации для любого типа, и тогда структуру составляли бы поля произвольно взятого объекта, но из-за контрвариантности CanRepresentAs по типу From это поломает сериализацию примитивов, так как возникнет конфликт при резолюции неявных параметров.
Сейчас я вижу такие варианты решения:
- Определить тип-маркер XMLRPCStruct и правила сериализации только для этого типа. Но это какой-то жабизм и вообще говнодизайн.
- Генерировать неявные значения макросами. Это ведёт к усложнению структуры проекта.
-
Сделать аналог CanRepresentAs, только с перламутровыми пуговицами инвариантный. Это дублирование кода. Поправка: это бред.
Какие ещё варианты может предложить лор-коммунити?