Контекст:
Я пытаюсь использовать полиморфизм c подтипа, предоставленного Джексоном, JsonSubTypes, в конечной точке RESTful. Существует некоторая общность между различными телами запросов, поэтому у меня есть:
abstract class A extends Translatable {
val infoA: String
val infoB: String
}
case class B(
infoA: String,
infoB: String,
infoC: String,
infoD: Int
) extends A {
override type T = B
def translate(
requestInfo: String,
request: B
): String = s"<$infoA,$infoB>:$infoC-${infoD.toString}"
}
case class C(
infoA: String,
infoB: String,
infoC: Array[String]
) extends A {
override type T = C
def translate(
requestInfo: String,
request: C
): String = s"<$infoA,$infoB>:${infoC.mkString}"
}
со следующей чертой, чтобы без необходимости сопоставлять входящий запрос A
с B
или C
:
trait Translatable {
type T <: A
def translate(
requestInfo: String,
request: T
): String
}
проблема в том, что, когда я компилирую, он жалуется на несоответствие типов:
found: request.type (with underlying type com.program.A)
required: request.T
Я пробовал несколько вещей, но безрезультатно, только с этим, казалось бы, близко:
- неявные ограничения обобщенного типа
e.g.,
def translate[X](
requestInfo: String,
request: X
)(implicit ev: X <:< A) = ...
(modifying the case class impl. of ^ accordingly)
, но это приводит к
Невозможно доказать, что com.program.A <: <request. T </p>
Есть мысли о том, как это сделать? Или я должен просто терпеть совпадение шаблонов? Я говорю, потому что первый блок кода работает тогда, когда я сопоставляю шаблон и вызываю конкретный импл. translate
для B
или C
, но я бы предпочел иметь параметр типа A
и вызывать translate
. Возможно ли это?
РЕДАКТИРОВАТЬ: Добавление случаев, когда вышеизложенное приводит к ошибкам компиляции:
class Program {
def doWork(
info: String,
request: A
): String = {
request.translate(
info,
request // compilation fails/complains about this param in both cases
)
}
}
РЕДАКТИРОВАНИЕ2: Добавление квалификации: мне нужно переопределить типы в подтипах, B
& C
, так что в переводе весело c. Я могу назвать поля, указанные c B
или C