I have an abstract Scala class Base which has subclasses Derived1 and Derived2. Base defines a function f() which returns an object of the same type as its implementing class. So Derived1.f() returns Derived1 and Derived2.f() returns Derived2. How do I write this in Scala?
Here is what I have come up with so far.
package com.github.wpm.cancan
abstract class Base {
def f[C <: Base]: C
}
case class Derived1(x: Int) extends Base {
def f[Derived1] = Derived1(x + 1)
}
case class Derived2(x: Int) extends Base {
def f[Derived2] = Derived2(x + 2)
}
This gives the following compiler errors:
type mismatch;
[error] found : com.github.wpm.cancan.Derived1
[error] required: Derived1
[error] def f[Derived1] = Derived1(x + 1)
type mismatch;
[error] found : com.github.wpm.cancan.Derived2
[error] required: Derived2
[error] def f[Derived2] = Derived2(x + 2)
This error message is confusing to me because I think com.github.wpm.cancan.Derived1 should be the same as Derived1 in this context.
Randall Schulz pointed out one of the reasons your current code doesn’t work. It is possible to get what you want, though, with F-bounded polymorphism:
The type parameter on the base trait allows you to talk about the implementing class there—e.g. in the return type for
f.