如何进行以下工作?
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)
bar
行产生错误:
type mismatch; found : x.type (with underlying type T0) required: Foo.this.t.I
(有人可能会说为什么pimp和bar
与apply
中的T
做同样的事情。但这是因为我减少了问题。在我的工作代码中,我有一个Seq [T]作为bar
的参数。)
修改
由于@AlexeyRomanov的回答,我展示了一个例子(也从工作代码中减少了)也应该有用:
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
答案 0 :(得分:5)
它不起作用,因为它不健全。假设它有效,那么我们可以这样做:
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)
但是ta.apply
需要TB
类型的元素,而不是TA
!
所以,基本上,你编写的代码并不代表你心中的类型关系。
答案 1 :(得分:1)
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)