Scala路径依赖类型:从引用到成员val对象的类型似乎不同于直接来自原始val对象的类型?

Int*_*tor 1 scala

我的头衔可能并不是真的很好地描述了这个问题.对于我正在做的事情,我不需要这个问题的答案,我现在的事情是正确的,但是当我使用Scala组合器解析器时,我遇到了这个让我感到困惑的问题.我想更好地理解语言(我大部分时间都是Scala新手),所以我想我会看到是否有人可以向我解释这个:

这是代码:

package my.example

import scala.io.Source
import scala.util.parsing.input.StreamReader
import scala.util.parsing.combinator.lexical.StdLexical
import scala.util.parsing.combinator.syntactical.StandardTokenParsers

class DummyParser extends StandardTokenParsers
{
    def scan
    (
        filename : String
    ) : Unit =
    {
        // Read in file
        val input = StreamReader( Source.fromFile( filename ).bufferedReader )
        // I want a reference to lexical in StandardTokenParsers
        val mylexical = lexical
        // Even if I put a type above like these two below it does not help
        // val mylexical : StdLexical = lexical
        // val mylexical : Tokens = lexical
        val tokensGood : lexical.Scanner = new lexical.Scanner( input )
        /*
        Compile error in following line:
        error: type mismatch;
        found   : mylexical.Scanner
        required: DummyParser.this.lexical.Scanner
        */
        val tokensBad : lexical.Scanner = new mylexical.Scanner( input )
    }
}
Run Code Online (Sandbox Code Playgroud)

"val tokensBad"行获得注释中显示的编译错误.上面的mylexical不是引用与this.lexical完全相同的对象(在上面的类派生的StandardTokenParsers中定义).阅读"Scala编程"我想我有点理解lexical.Scanner的类型是路径依赖的(第20.7节),但不应该是lexical.Scanner和mylexical.Scanner是同一类型的?词汇和mylexical不是同一个对象吗?哎呀,第426页书中的狗食示例似乎说来自两只不同的狗的SuitableFood类型是相同的,在我的情况下它是完全相同的对象(我认为).这里到底发生了什么?

Iul*_*gos 8

你想编译器来考虑lexical.Scannermylexical.Scanner平等的基础上的事实,在运行时的价值mylexical,并lexical始终是相同的.这是一个运行时属性,类型检查器不进行任何数据流分析(这样做太慢而不实用).

因此,您需要通过告诉它两个值始终相同来帮助类型检查器.你可以用a来做到这一点singleton type.单例类型是一种只有一个值的类型,并且写为(在本例中)lexical.type.

如果您将定义更改mylexical为:

val mylexical: lexical.type = lexical
Run Code Online (Sandbox Code Playgroud)

你的程序类型检查.

我们刚刚做的是告诉类型检查器mylexical在运行时只能有一个值,由单例类型给出.