расширяющий признак scala с методами, обеспечивающими различные типы, несоответствие типов

#scala #types #traits

#scala #типы #Трейты

Вопрос:

Я делаю что-то вроде этого:

 sealed trait Foo[T] {
  def getA: Decoder[T]
  def getB: Either[Type1, Type2]
}

trait Hello[T] extends Foo[T] {
  def getA: Decoder[T]
  def getB: Type1
}

trait World[T] extends Foo[T] {
  def getA: Decoder[T]
  def getB: Type2
}
  

В настоящее время либо неправильный способ определения всех типов. Как это решить?

Ответ №1:

Вы можете попытаться сузить возвращаемый тип в дочерних признаках

 trait Hello[T] extends Foo[T] {
  def getA: Decoder[T]
  def getB: Left[Type1, Type2]
}

trait World[T] extends Foo[T] {
  def getA: Decoder[T]
  def getB: Right[Type1, Type2]
}
  

Или вы можете попытаться ввести член типа

 sealed trait Foo[T] {
  def getA: Decoder[T]
  type Out
  def getB: Out
}

trait Hello[T] extends Foo[T] {
  def getA: Decoder[T]
  type Out = Type1
  def getB: Type1
}

trait World[T] extends Foo[T] {
  def getA: Decoder[T]
  type Out = Type2
  def getB: Type2
}
  

Или вы можете попробовать класс типов

 sealed trait Foo[T] {
  type This <: Foo[T]
  def getA: Decoder[T]
  def getB(implicit tc: TC[T, This]): tc.Out
}

trait Hello[T] extends Foo[T] {
  type This <: Hello[T]
  def getA: Decoder[T]
}

trait World[T] extends Foo[T] {
  type This <: World[T]
  def getA: Decoder[T]
}

trait TC[T, F <: Foo[T]] {
  type Out
}
object TC {
  implicit def hello[T, F <: Hello[T]]: TC[T, F] { type Out = Type1 } = null
  implicit def world[T, F <: World[T]]: TC[T, F] { type Out = Type2 } = null
}