Scala generics this.type

Я пытаюсь создать общий признак, который имеет метод, который возвращает экземпляр самого класса. Например:

trait SomeGenericTrait[T]{
   def withData(newData : Seq[T]) : this.type
}

case class SomeImpl(data : Seq[Int]) extends SomeGenericTrait[Int] {
   override def withData(newData : Seq[Int]) : SomeImpl = copy(data = newData)
}

error: overriding method withData in trait SomeGenericTrait of type(newData: Seq[Int])SomeImpl.this.type; method withData has incompatible type

Без явного типа возврата:

case class SomeImpl(data : Seq[Int]) extends SomeGenericTrait[Int] {
   override def withData(newData : Seq[Int]) = copy(data = newData)
}

error: type mismatch;
 found   : SomeImpl
 required: SomeImpl.this.type

Это не withData компиляции, потому что возвращаемое значение реализованной withData является SomeImpl но ожидаемый тип возвращаемого значения, основанный на объявлении метода trait, является SomeImpl.this.type.

Кто-нибудь знает, как мне нужно изменить возвращаемый тип декларации метода признаков, чтобы это работало? Более общий прецедент, который у меня есть, - это способ разоблачить метод copy класса case через общий признак, который он расширяет. Я знаю, что я не могу четко сформулировать это, дайте мне знать, если я что-нибудь разъясню.

Использование Scala 2.10.0

Ответы

Ответ 1

Вы можете решить его, параметризуя признак с типом типа класса, в который вы смешиваете:

trait SomeGenericTrait[T, X] {
  def withData(newData: Seq[T]): X
}

case class SomeImpl(data: Seq[Int]) extends SomeGenericTrait[Int, SomeImpl] {
  override def withData(newData: Seq[Int]): SomeImpl = copy(data = newData)
}

this.type - это одноэлементный тип - тип одного конкретного экземпляра SomeGenericTrait.