类型细化

时间:2011-11-06 15:00:44

标签: scala types

如何进行以下工作?

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和barapply中的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

2 个答案:

答案 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)