Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala generics this.type

Tags:

generics

scala

I'm trying to create a generic trait which has a method that returns an instance of the class itself. For example:

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

Without explicit return 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

This fails compilation because the return value of the implemented withData is SomeImpl but the expected return type based on the trait's method declaration is SomeImpl.this.type.

Does anyone know how I need to change the return type of the trait method declaration so this will work? The more general use case I have is a way to expose a case class' copy method through a generic trait it extends. I know I may not be articulating this clearly, let me know if I should clarify anything.

Using Scala 2.10.0

like image 263
driangle Avatar asked Nov 23 '13 17:11

driangle


People also ask

What is type parameter in Scala?

Language. Methods in Scala can be parameterized by type as well as value. The syntax is similar to that of generic classes. Type parameters are enclosed in square brackets, while value parameters are enclosed in parentheses.

How do you declare a generic type in a class explain?

If we want the data to be of int type, the T can be replaced with Integer, and similarly for String, Character, Float, or any user-defined type. The declaration of a generic class is almost the same as that of a non-generic class except the class name is followed by a type parameter section.

What is type in Scala?

Scala is a statically typed programming language. This means the compiler determines the type of a variable at compile time. Type declaration is a Scala feature that enables us to declare our own types.

How do you define a generic class in Java?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.


1 Answers

You can solve it by parameterizing the trait with type type of class you're mixing into:

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 is a singleton type - the type of one specific instantiated SomeGenericTrait.

like image 185
Knut Arne Vedaa Avatar answered Oct 19 '22 21:10

Knut Arne Vedaa