对引用的抽象类型的实际类型的混淆

时间:2017-01-04 02:53:07

标签: scala types type-alias

下面我有一个故意复杂的Hello World应用程序,其中我无法弄清楚为什么buildAndRun2方法不能编译。

abstract class BaseFactoryOf[A]{
    type TheType
    def make: TheType
}

abstract class FactoryOf[A] extends BaseFactoryOf[A]{
    final type TheType = A
}

class HelloWorld {
    def execute: String = "Hello World!"
}

class HelloWorldFactory extends FactoryOf[HelloWorld] {
    def make: TheType = new HelloWorld
}

def buildAndRun1[T <: BaseFactoryOf[_],B](factory: T)(f: T#TheType => B): B ={
    f(factory.make)
}

def buildAndRun2[T <: FactoryOf[_],B](factory: T)(f: T#TheType => B): B ={
    f(factory.make)
} //This doesn't compile due to a type mismatch error. But Why?!

//Client Code
buildAndRun1(new HelloWorldFactory)(i => i.execute) // This Works!
buildAndRun2(new HelloWorldFactory)(i => i.execute) // Epic Fail!

实际上编写了无用的中级FactoryOf[A]来介绍这个问题。我很确定这与type TheType有关但是它是什么?!如果有的话,那就是无用的中级FactoryOf类允许我验证type TheTypeA是否相同所以通过这种逻辑,我应该更自信地使用buildAndRun2方法

1 个答案:

答案 0 :(得分:1)

尝试

def buildAndRun3[T <: FactoryOf[_],B](factory: T)(f: factory.TheType => B): B = {
    f(factory.make)
}

我怀疑在TheType类型中定义了FactoryOf以依赖于参数。这就是为什么实际类型取决于给定的实际实例(路径依赖类型)而不仅仅是类型。

另一方面,buildAndRun1编译因为TheType未在类型BaseFactoryOf中定义,并且应该在另一个类型T中定义,这是一个后代。它可能被定义为持久性的东西,如Int