Scala 特质类型参数推断

Scala 特质类型参数推断,scala,Scala,为什么Scala编译器不能将Y的类型参数A推断为Int trait X[A] trait Y[A] extends X[A] object Foo extends X[Int] with Y 如果Y可以知道X的类型参数,而不必在Foo的声明中指定两次,我是否可以这样做?我也无法获得一个自类型解决方案。Scala不支持在类型声明中推断(和省略)类型构造函数参数。这可能在未来基于点演算的Scala版本中实现,该版本试图统一类型参数和类型成员 例如,请参见奥德斯基演讲的幻灯片(幻灯片29ff)。

为什么Scala编译器不能将
Y
的类型参数
A
推断为
Int

trait X[A]

trait Y[A] extends X[A]

object Foo extends X[Int] with Y

如果
Y
可以知道
X
的类型参数,而不必在
Foo
的声明中指定两次,我是否可以这样做?我也无法获得一个自类型解决方案。Scala不支持在类型声明中推断(和省略)类型构造函数参数。这可能在未来基于点演算的Scala版本中实现,该版本试图统一类型参数和类型成员


例如,请参见奥德斯基演讲的幻灯片(幻灯片29ff)。

此表单中是否需要类型参数?在某些情况下,可以使用以下解决方案:

trait X { type A /* type parameter as member */ }
trait Y extends X
object Foo extends Y { type A = Int /* equivalent to Y[Int] or X [Int] */ }
它可以用在定义中

trait X {
  type A 
  def xfun: A
}
trait Y extends X { def tuple[K](k: K): (K, A) = (k -> xfun) }
object Foo extends Y {
  def xfun = System.identityHashCode(this)
  type A = Int
}
然后,如果测试:

scala> Foo.tuple("test")
res0: (String, Foo.A) = (test,2088931356)

对于某些用例,使用中间类可以解决问题:

import scala.reflect.runtime.universe._

abstract class XBase {
  type A
  def say(a : A) : Unit = println(a)
}

trait Y extends XBase {
  override def say(a : A) : Unit = { 
      println("Hello ")
      super.say(a)
  }
}

class X[B : TypeTag] extends XBase {
   type A = B
}

object Foo extends X[Int] with Y

为什么不让对象Foo扩展Y[Int]?要扩展@LimbSoup的答案,因为Y[A]已经扩展了X[A],所以要在X[A]中混合两次。有什么特别的原因吗?公平的问题。我需要几个
Y
类型,因此我要遵从编译器以合理的方式对它们进行线性化(我认为这回答了@Mario的问题)。