Scala:为什么抽象类型成员等于类型参数=:=不等于使用?

hol*_*ech 1 generics types scala

我开始在类型参数上使用抽象类型成员 - 主要是因为它们似乎对我的类型推断更好.但是,我仍然在努力理解如何从它们所定义的类型之外使用它们.例如,我无法理解为什么以下Scala程序不应该编译:

trait Thing

trait Describer {
  type X<:Thing
  def describe(x:X) = println(x)
}

object Program extends App {

  def print[T <: Thing, D <: Describer]
    (describer: D, thing:T)
    (implicit ev: D#X =:= T) 
    = describer.describe(thing) 

}
Run Code Online (Sandbox Code Playgroud)

直觉上,我希望这个要求D#X =:= T可以保证两种类型确实相等,因此两个实例可以互换使用,但是我得到了这个编译错误:

error: type mismatch;
 found   : thing.type (with underlying type T)
 required: describer.X
    = describer.describe(thing)
Run Code Online (Sandbox Code Playgroud)

我误解了什么?有没有其他方法可以做我想做的事情?或者失败,是否可以安全地thing转换为所需的类型(describer.X)?

Jas*_*r-M 5

参数的类型describer.describe实际上是describer.X和不是D#X.另一件你必须知道的是,它A =:= B也可以作为转换A,B但(至少目前)不是相反的方式.所以以下应该有效.

def print[T <: Thing]
  (describer: Describer, thing: T)
  (implicit ev: T =:= describer.X) 
  = describer.describe(thing) 
Run Code Online (Sandbox Code Playgroud)