why trait method needs asInstanceOf and class method don't
generics, scala, traits
Solution
The parameter of mult must be of type `T`.
When calling `mul(this)`, the this parameter is of type `Felem[T]`, which is not and does not conform to `T`. There is the additional constraint that `T` conforms to `Felem[T]`. But this is not what you want, you would need the opposite, `Felem[T]` to conform to `T`.
On the other hand, in `F2elem`, `T` is exactly `F2elem`, so it typechecks (completley unrelated to one being a trait and the other one a class)
Here is example to show that the definition in `Felem` must indeed not typecheck, and that it is possible to have implementors where `Felem[T]` does not conform to `T`.
class F3elem extends Felem[F2elem] // this is 2, not 3
This declaration is correct, `F2elem` which is given for `T` satisfies `T <: Felem[T]`. However, an inherited t`his.mul(this)` in `square` would be invalid, mult expect a `T`, that is `F2elem`, and this is `F3elem`. And they are unrelated.
What you probably want is that every `Felem` must be like `F2elem`, that is that `T` must be the type of the actual class. You can enforce this with a self type.
trait Felem [T <: Felem[T]] { this: T => /* your code */ }
When you write that, you state that in every implementation, the type of the implementation must conform to `T`. Doing that, it will typecheck, and you will not be allowed to instanciate F3elem above :
error: illegal inheritance; self-type F3elem does not conform to Felem[F2elem]'s selftype F2elem class F3elem extends Felem[F2elem] {
Problem
I have defined the following trait: ``` trait Felem[T <: Felem[T]] { def mul(that: T): T def square: T = this.mul(this.asInstanceOf[T]) } ``` I also define a class based on this trait: ``` class F2elem(val coef: Boolean) extends Felem[F2elem] { override def square: F2elem = this.mul(this) ... } ``` My questions are about the need of "asInstanceOf" in the definition of the "square" method in the trait. If I remove it, I get the following error: ``` error: type mismatch; found : Felem.this.type (with underlying type Felem[T]) required: T def square: T = this.mul(this) ``` - Why is it needed in the trait ? - Why it is not needed in the class ? - Does it cost anything in term of execution time or memory ?