Reputation: 5844
How can I make the following work?
trait T {
type I <: T
def apply(i: I): I
}
class Foo[T0 <: T](t: T0) {
def bar(x: T0) = t(x)
}
implicit def tofoo[T0 <: T](t: T0) = new Foo(t)
The bar
line yields the error:
type mismatch; found : x.type (with underlying type T0) required: Foo.this.t.I
(One might argue why pimp and having bar
doing the same as apply
in T
. But it´s because I reduced the problem. In my working code I have a Seq[T] as a parameter of bar
.)
EDIT:
Due to the answer of @AlexeyRomanov I show an example (also reduced from working code) what also should work:
trait T {
type I <: T
def apply(i: I): I
}
class Foo[T0 <: T { type I = T0 }](val t: T0) {
def bar(x: T0) = t(x)
def test = "!"
}
implicit def tofoo[T0 <: T { type I = T0 }](t: T0) = new Foo(t)
trait TA extends T {
type I = TA
}
case class TB() extends TA {
def apply(i: I): I = i
}
println(TB().test) // ERROR: value test is not a member of TB
Upvotes: 1
Views: 1813
Reputation: 297265
It doesn't work because it is not sound. Suppose it worked, then we could do this:
trait T {
type I <: T
def apply(i: I): I
}
class Foo[T0 <: T](t: T0) {
def bar(x: T0) = t(x)
}
class TA extends T {
type I = TB
def apply(i: I): I = i
}
class TB extends T {
type I = T
def apply(i: I): I = i
}
val ta = new TA
val foo = new Foo(ta)
foo.bar(ta) // calls ta(ta)
But ta.apply
expects an element of type TB
, not TA
!
So, basically, the code you wrote does not represent the type relationships you have in your mind.
Upvotes: 5
Reputation: 170805
class Foo[T0 <: T {type I = T0}](val t: T0) {
def bar(x: T0) = t(x)
}
implicit def tofoo[T0 <: T {type I = T0}](t: T0) = new Foo(t)
Upvotes: 1