Как расширить сигнатуру типа Scala на подклассы?

Я определил трейт Super[A] с одним абстрактным методом и несколькими конкретными методами, многие из которых просто создают новый экземпляр объекта с некоторыми изменениями. Вот пример:

trait Super[A] { self =>

  def abstractMethod: A

  def map[B](f: A => B): Super[B] = new Super[B] {
    def abstractMethod = f(self.get)
  }
}

Теперь я хотел бы создать несколько классов, которые наследуются от Super[A] без изменения возвращаемого типа каждого конкретного метода.

Какой самый идиоматический способ добиться такого результата?


person Filippo Costa    schedule 21.10.2016    source источник
comment
Если вам нужна реализация для какого-то конкретного типа A, вы можете сделать class Impl extends Super[String], если вам нужна реализация для какого-то универсального типа A - вы можете сделать class Impl[A] extends String[A]. Я не знаю всей задачи, над которой вы работаете, но в качестве альтернативы вы можете рассмотреть классы типов.   -  person I See Voices    schedule 22.10.2016
comment
Я смущен тем, почему вы хотите изменить возвращаемые типы. Не могли бы вы показать пример класса, который наследуется от Super[A], где вам (нужно) изменить возвращаемый тип каждого конкретного метода?   -  person TeWu    schedule 22.10.2016
comment
Мне нужно, чтобы каждый конкретный метод возвращал экземпляр конкретного класса, а не экземпляр Super   -  person Filippo Costa    schedule 22.10.2016


Ответы (1)


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

примечание: .get не был определен, поэтому вместо этого я использовал .abstractMethod в .map

trait Super[A] { self =>
  def abstractMethod: A

  def map[B](f: A => B) = new Super[B] {
    def abstractMethod = f(self.abstractMethod)
  }
}

пара занятий

class X(val n: Int) extends Super[X] {
  def abstractMethod = this
  def toY = new Y(n)
}

class Y(val n: Int) extends Super[Y] {
  def abstractMethod = this
  def toX = new X(n)
}

работает как положено

val x:  X = new X(999)
val y:  Y = x.map(_.toY).abstractMethod
val x2: X = y.map(_.toX).abstractMethod

val sup_x:  Super[X] =     x.map(_.abstractMethod)
val sup_y:  Super[Y] =     x.map(_.toY)
val sup_y2: Super[Y] = sup_x.map(_.toY)
val sup_x2: Super[X] = sup_y.map(_.toX)
person kmh    schedule 21.10.2016