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