使用scala.Singleton作为类型约束是不一致的?

时间:2015-03-06 22:36:49

标签: scala types

我在scala中运行了一些使用Singleton的示例,并且遇到了看似不一致的问题。这是一个最小的例子:

trait X {
  type T <: Inner
  trait Inner {
    def innerMethod(config: T)
  }

  def outerMethod(config: T)
}

如果我这样做

def add[U <: X](a: U#T, b: U#T) = {
  a.innerMethod(b)
}

无法按预期编译,因为a可以是obj1.T类型而b可以是obj2.T类型,可以U约束Singleton {1}}解决了问题:

def add[U <: X with Singleton](a: U#T, b: U#T) = {
  a.innerMethod(b)
}

但是,以下内容也无法编译:

def add[U <: X with Singleton](a: U, b: U#T) = {
  a.outerMethod(b)
}

错误是:

  

错误:(15,21)类型不匹配;

     

发现:b.type(底层类型为U#T)

     

必需:a.T

似乎Singleton约束会强制Ua.type类型,然后b类型为a.T

知道发生了什么事吗?

1 个答案:

答案 0 :(得分:0)

我认为你期望T是对象无关的类型,而不是:对于类型X的每个对象,都有唯一的抽象T类型。

对于outerMethod,

def outerMethod(X#T) = ... 

应该够了, 对于innerMethod,调用函数的对象类型应该是相同的X#T。

检查出来

class Outer {
type T<: Inner
class Inner {
    def that(that:Outer#T) = that
}
def that(that:Outer#T) = that
}
class Outer2 extends Outer{
    type T = Inner
    val in = new T
}
object Obj {
    def add[U <: Outer](a: U#T, b: U#T) = {
        a.that(b)
    }
    def add[U<:Outer](a:U, b: U#T): Unit = {
        a.that(b)
    }
}
val out = new Outer2
Obj.add(out.in, out.in)
Obj.add(out, out.in)