I fail to understand why I am getting an “inferred type arguments do not conform to type parameter bounds”. First, I defined a trait called CS which may be implemented by several classes (e.g., CS01 and CS02):
trait CS[+T <: CS[T]] {
this: T =>
def add: T
def remove: T
}
class CS01 extends CS[CS01] {
def add: CS01 = new CS01
def remove: CS01 = new CS01
}
class CS02 extends CS[CS02] {
def add: CS02 = new CS02
def remove: CS02 = new CS02
}
The idea is to keep the implemented type when calling add
or remove
on CS01 and CS02.
Secondly, I would like to define operations that may be executed on every classes compliant with trait CS. Then, I defined a trait called Exec
(with two very simple examples of classes Exec01
and Exec02
mixin the Exec
traits):
trait Exec {
def exec[U <: CS[U]](x: U): U
}
class Exec01 extends Exec {
def exec[U <: CS[U]](x: U): U = x.add
}
class Exec02 extends Exec {
def exec[U <: CS[U]](x: U): U = x.remove
}
Once again, I need to keep the implemented type of the class that mixes the CS
trait. That is why exec is parametrized with [U <: CS[U]]
.
Finally, I want any CS
enabling operations on it to mixin the trait Executable
which makes it possible to execute an operation that follows trait Exec
:
trait Executable[T <: CS[T]] {
this: T =>
def execute(e: Exec): T = e.exec(this)
}
However, I get the following error when I am trying to compile:
error: inferred type arguments [this.Executable[T] with T] do not conform to method exec's type parameter bounds [U <: this.CS[U]]
def execute(e: Exec): T = e.exec(this)
^
I don't quite understand because any classes that mix Executable
must be of type T
with the constraint of mixin the CS trait due to the bound in trait Executable[T <: CS[T]]
. So, why this
does not conform to the type parameter bound U <: CS[U]
?
Works if you specify the type parameter to exec explicitly:
def execute(e: Exec): T = e.exec[T](this)
Seems to be a limitation in the type inference.