Scala: это расширение значений функций (не методов) - PullRequest
0 голосов
/ 26 сентября 2018

После экспериментов с расширением eta в scala я обнаружил странную особенность.Давайте определим метод:

scala> def sum(a: Int, b: Int): Int = a + b
sum: (a: Int, b: Int)Int

Хорошо, до сих пор все в порядке.Теперь давайте присвоим его значению val, используя расширение eta:

scala> val f = sum _
f: (Int, Int) => Int = $$Lambda$1051/694580932@55638165

Теперь странная вещь приближается.Я могу снова применить eta-расширение к f, и оно работает (однако оно добавляет карри к моему методу):

scala> val g = f _
g: () => (Int, Int) => Int = $$Lambda$1055/1351568309@5602e540

Почему это работает?Я думал, что расширение eta было допустимо только для методов.Более того, я заметил, что это невозможно:

scala> ((a: Int, b: Int) => a + b: Int) _
<console>:12: error: _ must follow method; cannot follow (Int, Int) => Int
       ((a: Int, b: Int) => a + b: Int) _
                         ^

Но разве это не то же самое, что применять расширение eta к f?Я немного сбит с толку, и эти eta-расширения все еще скрывают для меня магию.Большое спасибо!

1 Ответ

0 голосов
/ 27 сентября 2018

Когда вы пишете val f = sum _ на верхнем уровне REPL или объекта / класса, Scala определяет метод доступа, чтобы вы могли получить к нему доступ.Вот как Scala отлаживает это (через scalac -Xprint:typer на val f: (Int, Int) => Int = _ + _):

private[this] val f: (Int, Int) => Int = ((x$1: Int, x$2: Int) => x$1.+(x$2));
<stable> <accessor> def f: (Int, Int) => Int = Foo.this.f;

Итак, когда вы впоследствии пишете val g = f _, он выполняет eta-расширение для метода доступа с нулевым аргументом, которыйприводит к поведению, которое вы видите.Для дополнительной проверки обратите внимание, что, если вы поместите определения в метод, вы получите ошибку:

def foo = {
  val f: (Int, Int) => Int = _ + _
  val g = f _ // error: _ must follow method; cannot follow (Int, Int) => Int
}

Это происходит потому, что методы доступа генерируются только для полей (и определений REPL верхнего уровня, которыеобрабатываются как поля).

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