Как использовать литеральные параметры в коллекции массивов scala?

Мне нужна помощь для этого:

например:

val myArray= Array(1, 2, 4, 5, -1, -7, 11, 29)

Это я поняла: myArray.exists( _ < 0 )

И также я могу понять это: myArray.count(_ % 2 == 0)

но как я могу написать в REPL это:

myArray.forall( !xyz(_) )     xyz is this _ % 2 == 0 like above

Я получаю эту ошибку:

"error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.unary_$bang.$percent(2).$eq$eq(0(x$2)))
              myArray.count( !_ % 2 ==0(_) )"

У меня есть Eclipse 4.4. Luna.

3 ответа

Давайте посмотрим на вариант на одном из ваших примеров:

myArray.count(!(_ % 2 == 0))

В этом фрагменте, так как выражение _ % 2 == 0 заключен в скобки, компилятор разбирает его как анонимную функцию, а не как целую !(_ % 2 == 0) как и следовало ожидать.

Рассматривая то, что в скобках, как функцию, компилятор не знает, какой тип выводить для заполнителя. Вы можете подумать, что можете это исправить, добавив аннотацию, давая

myArray.count(!((_: Int) % 2 == 0))

Но это тоже не сработает, потому что вы на самом деле применяете унарный ! оператор анонимной функции, которую вы создали!

Чтобы обойти это, вы можете упростить свой предикат...

myArray.count(_ % 2 != 0)

... или полностью исключить заполнитель.

myArray.count(n => !(n % 2 == 0))


РЕДАКТИРОВАТЬ: Хотя приведенные выше предложения, вероятно, являются лучшим способом решения вашей проблемы, они не связаны непосредственно с сообщением об ошибке, которое вы получили, когда ввели следующее (недействительное) выражение:

myArray.count(!_ % 2 == 0(_))

Здесь есть две проблемы. Во-первых, ваша анонимная функция _ % 2 == 0 не заключено в круглые скобки, что приводит к тому, что компилятор полагает, что все выражение !_ % 2 == 0(_) является анонимной функцией двух переменных.

Если мы заключим нашу анонимную функцию в скобки, мы получим

myArray.count(!(_ % 2 == 0)(_))

Мы добились прогресса, так как компилятор больше не ищет два параметра, но он не может определить тип заполнителя во встроенной функции, поэтому мы должны аннотировать его.

Наконец, мы имеем

myArray.count(!((_: Int) % 2 == 0)(_))

Это работает как ожидалось. Это, конечно, не так элегантно, как решения, представленные выше, но это работает.

Это то же самое, что и в этом вопросе: Scala неожиданно не смогла определить тип для расширенной функции. Замечания: ! также функция

Используя _ дважды, вы определяете функцию с двумя параметрами - и действительно странным. Компилятор говорит вам, что он не может иметь смысла в вашем утверждении, в то время как он пытается получить типы двух параметров - что невозможно.

В случаях, прежде чем это было возможно, например, в

myArray.exists(_ < 0) 

Компилятор знает, что существует в Array[In t] ожидает функцию In t для Bool. Таким образом, код расширяется до

myArray.exists((x : Int) => x < 0) 

В вашем случае вы должны написать:

myArray.forall( _ % 2 != 0)

Альтернативой будет

def xyz(n: Int) = n % 2 == 0
myArray.forall(!xyz(_))

Лучшим сообщением об ошибке было бы что-то вроде "forall ожидает здесь функцию Int => Bool". Я думаю, что это невозможно из-за наличия у Scala последствий. Вы можете прочитать больше об этом материале в главе 8 книги Мартина Одерскиса Скала.

Другие вопросы по тегам