Почему scalac запутывается, когда мой тип SAM не реализует функцию, когда он перегружает 'andThen'? - PullRequest
2 голосов
/ 14 марта 2020

Протестировано с 2.13, но я полагаю, что это было так с 2.12, и я просто не сталкивался с такой проблемой раньше:

trait Extractor[-X, +Y] {
    def optional :X => Option[Y] = apply

    def apply(x :X) :Option[Y]

    def andThen[Z](extractor :Extractor[Y, Z]) :Extractor[X, Z] = {
        val first = optional; val second = extractor.optional
        Extractor { x :X => first(x).flatMap(second) }
    }

    def andThen[Z](req :Y => Z) :Extractor[X, Z] = {
        val first = optional
        Extractor { x :X => first(x).map(req) }
   }

   def compose[W](extractor :Extractor[W, X]) :Extractor[W, Y] = extractor andThen this

   def compose[W](req :W => X) :Extractor[W, Y] = Extractor(req andThen optional)

}

Scalac имеет жалобу crypti c о реализации первого compose:

Error:(44, 31) type mismatch;
found   : net.noresttherein.oldsql.morsels.Extractor[X,Y]
required: W => ?
def compose[W](extractor :Extractor[W, X]) :Extractor[W, Y] = extractor andThen this

Комментирование варианта andThen с использованием функции решает проблему. Так же, как и изменение кода на extractor.andThen[Y](this) (ключевым параметром здесь является явный параметр типа). Я предполагаю, что мой тип SAM каким-то образом повышается до функции, но я не могу догадаться, почему он имеет приоритет над методом. Поскольку я представил здесь два «решения», я ищу не столько обходных путей, сколько понять, что происходит. Впервые за многие годы я не понимаю, что происходит, и хотел бы устранить подобные проблемы в будущем.

1 Ответ

4 голосов
/ 14 марта 2020

Возможно, вы не согласны с новыми правилами разрешения перегрузки , которые предназначены для облегчения вывода типа.

Вопрос в том, что такое "ожидаемый тип" аргумента. in extractor.andThen(this).

"Интуиция для вывода типа параметра функции более высокого порядка состоит в том, что все аргументы должны быть функционально-подобного типа."

Таким образом, удаление разрывов метода apply это условие и позволяет продолжить набор.

Спецификация c добавляет: «Намерение не состоит в том, чтобы управлять разрешением перегрузки.»

Оно должно читать: «Намерение не состоит в том, чтобы нарушать разрешение перегрузки . "

Я полагаю, благие намерения были проложены много дорог .

Правка: работает в 2.12 без измененных правил. В старой системе нет ожидаемого типа, если метод перегружен.

Стоит добавить, что он, вероятно, квалифицируется как регрессия. Например, они могут выполнить резервную проверку типов в соответствии с предыдущими правилами.

Вот тикет для него.

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