2014-07-16 115 views
0

为什么Scala编译器不能推断出Y的类型参数AInt特征类型参数推断

trait X[A] 

trait Y[A] extends X[A] 

object Foo extends X[Int] with Y 

有没有一种方法,我可以做到这一点,其中Y可以了解的X类型参数没有Foo的声明,指明了两次?我无法获得自我打字的解决方案。

+1

为什么你不只是有'对象foo Y延伸[INT]'? –

+0

为了扩展@ LimbSoup的答案,由于Y [A]已经扩展了X [A],所以你在X [A]中混合了两次。有什么特别的原因? –

+0

公平的问题。我会需要几个'Y'类型,所以我要推迟到编译器以合理的方式对它们进行线性化处理(我认为这回答@ Mario的问题)。 –

回答

0

Scala不支持类型声明中类型构造函数参数的推理(和省略)。这可能在未来的基于DOT演算的Scala版本中尝试统一类型参数和类型成员。

参见Odersky的演讲幻灯片The Trouble With Types(幻灯片29ff)的幻灯片。

0

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

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) 
1

对于一些使用情况,使用中间类可以解决这个问题:

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