Типы, зависящие от пути Scala: тип из ссылки на членский объект val, кажется, отличается от того, что тип поступает непосредственно из исходного объекта val? - PullRequest
1 голос
/ 22 декабря 2011

Возможно, мой заголовок не очень хорошо описывает проблему. Мне не нужен ответ на этот вопрос из-за того, что я делаю, у меня сейчас все правильно, но пока я работал с синтаксическими анализаторами 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 )
    }
}

Строка "val tokensBad" возвращает ошибку компиляции, показанную в комментариях. Разве mylexical не ссылается на тот же объект, что и this.lexical (определенный в StandardTokenParsers, из которого получен вышеприведенный класс). Читая «Программирование в Scala», я думаю, что я вроде понимаю, что тип lexical.Scanner зависит от пути (Раздел 20.7), но не должны ли lexical.Scanner и mylexical.Scanner быть одного типа? Разве лексический и милексический не один и тот же объект? Черт возьми, пример собачьего корма в книге на странице 426, кажется, говорит, что тип подходящего корма для двух разных собак одинаков, и в моем случае выше его точно такой же объект (я думаю). Что на самом деле здесь происходит?

1 Ответ

8 голосов
/ 22 декабря 2011

Вы бы хотели, чтобы компилятор считал lexical.Scanner и mylexical.Scanner равными, исходя из того факта, что во время выполнения значения mylexical и lexical всегда одинаковы.Это свойство времени выполнения, и средство проверки типов не выполняет никакого анализа потока данных (это было бы слишком медленно, чтобы быть практичным).

Так что вам нужно помочь проверке типов, сказав, что эти два значения всегда одинаковы.Вы можете сделать это, используя singleton type.Тип Singleton - это тип, который имеет ровно одно значение и записывается как (в данном случае) lexical.type.

Если вы измените определение mylexical на:

val mylexical: lexical.type = lexical

ваша программа проверяет тип.

Мы только что сказали контролеру типов, что mylexical может иметь только одно значение во время выполнения, заданное типом singleton.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...