Каков наилучший способ избежать столкновения между двумя определениями класса типов в бесформенном

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

Чтобы использовать механизм деривации в качестве пользователя класса типов, вы должны использовать следующий синтаксис

import MyTypeClass.auto._

что, насколько я понимаю, эквивалентно

import MyTypeClass.auto.derive

Проблема возникает, когда вы пытаетесь использовать несколько подобных классов типов в одной области видимости. Может показаться, что компилятор Scala учитывает только последнее определение функции наследования, даже несмотря на то, что существуют две версии функции, «перегруженные» своими неявными аргументами.

Есть несколько способов, которые я могу придумать, чтобы исправить это. Вместо того, чтобы перечислять их здесь, я отмечу их как ответы, за которые вы можете проголосовать, чтобы подтвердить здравомыслие, а также предложить любое лучшее решение.


person jedesah    schedule 26.08.2014    source источник


Ответы (3)


Я поднимал этот вопрос еще в апреле и предлагал два решения: определить метод самостоятельно (как вы предлагаете) :

object AutoCodecJson {
  implicit def deriveEnc[T] = macro deriveProductInstance[EncodeJson, T]
  implicit def deriveDec[T] = macro deriveProductInstance[DecodeJson, T]
}

Или используя импорт псевдонимов:

import AutoEncodeJson.auto.{ derive => deriveEnc }
import AutoDecodeJson.auto.{ derive => deriveDec }

Я бы настоятельно рекомендовал импортировать псевдонимы — сам Майлз сказал, что "не ожидал, что макрос повторно используется таким образом: не уверен, что одобряю" подход deriveProductInstance.

person Travis Brown    schedule 26.08.2014
comment
Интересно, что я предпочитал первый подход второму, потому что он требовал меньше работы (не говоря уже о знаниях) со стороны пользователя. - person jedesah; 26.08.2014
comment
Согласен, но сочетание дополнительной зависимости scala.reflect и зависимости от не совсем ориентированной на пользователя части Shapeless API, вероятно, в большинстве случаев перевешивает это преимущество. - person Travis Brown; 26.08.2014
comment
Это больше не похоже на проблему с Shapeless 2.1. - person jedesah; 10.02.2015

Вместо того, чтобы наследовать от трейта Companion, определите объект auto и метод apply самостоятельно в своем объекте-компаньоне и назовите их отчетливо. Возможным недостатком этого является то, что две отдельные библиотеки, использующие shapeless, могут в конечном итоге определить метод наследования с тем же именем, и пользователь снова окажется в ситуации, когда он не может использовать процесс наследования для обоих классов типов в одной и той же области в своей области. проект.

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

person jedesah    schedule 26.08.2014

Измените/исправьте компилятор Scala, чтобы он принимал два разных метода, перегруженных для их неявных параметров.

Есть ли причина, по которой это невозможно в теории?

person jedesah    schedule 26.08.2014
comment
Это сломало бы большую часть существующего кода, где определение имплицита с тем же именем часто используется в качестве обходного пути для отключения имплицита. - person Travis Brown; 26.08.2014
comment
О, интересно, это веская практическая причина, о которой я не подумал. Я предполагаю, что кто-то, разрабатывающий преемника Scala, может разрешить переопределение неявных параметров и иметь другой механизм для удаления определений из области видимости. не импортировать? - person jedesah; 26.08.2014