Типирование скалы требует неявного
Я пытаюсь построить следующее
У меня есть родительский родовой класс
abstract class ResultProvider[+T: Writes](db: DB) {
def get(id: Long): Future[Seq[T]]
}
И некоторые реализации, например
class LengthProvider(db: DB) extends ResultProvider[LengthResult](db){
override def get (userId: Long): Future[Seq[LengthResult]] = ...
}
object LengthProvider extends ((DB) => DisciplinePredictor) {
override def apply(db: DB) = new LengthProvider(db)
}
У меня есть следующая карта конфигурации:
val providers: Map[String, ((DB) => ResultProvider[???])] = Map(
"length" -> LengthProvider,
"width" -> WidthProvider,
...
)
Мой вопрос, что я должен поставить вместо???. В идеале это должно быть что-то вроде T : Writes
, как я только забочусь, что этот тип имеет Writes
имплицитно реализовано, так как я собираюсь Json.toJson
Это. Это будет компилироваться с Any
, но тогда информация, которую должен реализовать класс Writes
неявное потеряно. Или я должен использовать другой подход? Я мог бы, вероятно, создать суперкласс для всех моих классов прецедентов (например,LengthResult
), но я хочу сойти с рук.
1 ответ
Вы должны быть в состоянии написать ResultProvider[_]
(ищите "экзистенциальные типы", если вы не знакомы с этим синтаксисом), но вам нужно дать имя неявному:
abstract class ResultProvider[+T](db: DB)(implicit val writes: Writes[T]) { ... }
В другом месте:
val provider: ResultProvider[_] = providers("length")
import provider.writes // makes the implicit visible here
...
Возможно, вам придется помочь компилятору (или вам самим, если вам нужно назвать тип), предоставив переменную типа:
providers("length") match {
case provider: ResultProvider[a] =>
import provider.writes
...
}