Оставить подчеркивание в литературе функций?

scala> val alist = List(1,2,3,4,5)
alist: List[Int] = List(1, 2, 3, 4, 5)

scala> alist filter { 2.< }
res2: List[Int] = List(3, 4, 5)

scala> alist filter { 2 < }
res3: List[Int] = List(3, 4, 5)

scala> alist filter { > 3 }
<console>:1: error: ';' expected but integer literal found.
       alist filter { > 3 }

Почему работают { 2.< } и {2 <}? Думаю, по крайней мере, я должен написать { 2 < _ } правильно?

Метод, который не требует аргументов, вы также можете опустить точку и использовать постфиксную запись оператора:

scala> val s = "Hello, world!"
s: java.lang.String = Hello, world!
scala> s toLowerCase
res4: java.lang.String = hello, world!

Но здесь метод < - это не те методы, которые не требуют правильных аргументов?

Можете ли вы указать мне, что это за использование?

Ответы

Ответ 1

Что происходит, это расширение Eta (6.26.5):

Eta-расширение преобразует выражение типа метода в эквивалентное выражение типа функции.

В этом случае 2 < - это тип метода: (один из) метод < на Int. Однако filter ожидает тип функции. В этом случае Scala выполняет автоматическое расширение.

Обратите внимание, что, поскольку тип, ожидаемый с помощью filter, известен, он может правильно вывести метод 2 <.

Ответ 2

Причиной этого является то, что 2 является объектом, поэтому, если вы пишете 2.< или 2 < (которые на самом деле одинаковы в Scala), вы вызываете метод < на объект 2.

Если вы просто пишете < или >, компилятор будет искать такой метод в локальной области, но не найдет его. Аналогично, пишу > 3, компилятору нужен доступный метод >, который не является.

Вы также можете увидеть это поведение в консоли напрямую:

scala> 3.<
<console>:8: error: ambiguous reference to overloaded definition,
both method < in class Double of type (x: Char)Boolean
and  method < in class Double of type (x: Short)Boolean
match expected type ?
               3.<
                 ^

Как вы видите, существует несколько определенных импликтивов, которые превращают 3 в объект класса, который определяет метод <. Так что это работает в принципе, но не может стоять на своих собственных. Однако он работает, если у вас больше информации о типе, например, в вашем примере.

Сравните это со следующим:

scala> <(3)
<console>:8: error: not found: value <
              <(3)
              ^

Здесь вы можете увидеть, как компилятор ищет автономный <. Обратите внимание, что в сообщении об ошибке указано значение, но это все равно означает, что это может быть функция, поскольку тип значения может быть (Int, Int) => Boolean или что-то в этом роде.

Ответ 3

2.< относится к методу < объекта 2, тогда как 2.<(_) возвращает новую функцию с одним аргументом. Последний является ярлыком для (расширяется до) (x: Int) => 2 < x, где тип Int был выведен компилятором scala из типа элементов alist.

> 3 в вашем случае не ссылается ни на какой метод или объект какого-либо объекта. > является юридическим идентификатором scala (для метода, функции или объекта), но 3 не является юридическим идентификатором (он начинается с цифры). > a может быть ссылкой на элемент a объекта > (>.a). Но ни один из них не существует в вашем примере. _ > 3 однако возвращает новую функцию с одним аргументом, который вы также можете написать (x: Int) => x > 3.

Это по сути то же самое, что Даниэль С. Собрал отвечает и компрометирует комментарий Фрэнку, но менее формальный и с большим количеством примеров. Надеюсь, что это поможет получить интуицию.