Reputation: 13
I need help for this:
for example:
val myArray= Array(1, 2, 4, 5, -1, -7, 11, 29)
I understand this : myArray.exists( _ < 0 )
And also I can understand this: myArray.count(_ % 2 == 0)
but how I can write at REPL this:
myArray.forall( !xyz(_) ) xyz is this _ % 2 == 0 like above
I get this error:
"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(_) )"
I have Eclipse 4.4. Luna.
Upvotes: 1
Views: 197
Reputation: 97
Let's look at a variation on one of your examples:
myArray.count(!(_ % 2 == 0))
In this snippet, since the expression _ % 2 == 0
is enclosed in parentheses, the compiler parses it as an anonymous function by itself, rather than the entire !(_ % 2 == 0)
as you might expect.
Treating what's in parentheses as a function, the compiler doesn't know what type to infer for the placeholder. You might think you could fix this by adding an annotation, giving
myArray.count(!((_: Int) % 2 == 0))
But this won't work either, because you are actually applying the unary !
operator to the anonymous function you've created!
To get around this, you could either simplify your predicate...
myArray.count(_ % 2 != 0)
...or eliminate the placeholder altogether.
myArray.count(n => !(n % 2 == 0))
EDIT: Although the suggestions above are probably the best ways to solve your problem, they do not directly address the error message you received when you entered the following (invalid) expression:
myArray.count(!_ % 2 == 0(_))
There are two problems here. The first is that your anonymous function _ % 2 == 0
is not wrapped in parentheses, leading the compiler to believe that the entire expression !_ % 2 == 0(_)
is an anonymous function of two variables.
If we wrap our anonymous function in parentheses, we have
myArray.count(!(_ % 2 == 0)(_))
We've made progress, as the compiler is no longer looking for two parameters, but it cannot infer the type of the placeholder in the embedded function, so we must annotate it.
Finally, we have
myArray.count(!((_: Int) % 2 == 0)(_))
This works as expected. It's certainly not as elegant as the solutions presented above, but it does work.
Upvotes: 1
Reputation: 98
This is the same as in this question: Scala unexpectedly not being able to ascertain type for expanded function. Note: !
also a function
Upvotes: 0
Reputation: 1109
By using _ twice you are defining a function with two parameters - and a really weird one that is. The compiler tells you that it cannot make sense of your statement while it tries to derive the types of the two parameters - which is impossible.
In the cases before this was possible, for example in
myArray.exists(_ < 0)
the compiler knows that exists on a Array[Int] expects a function Int to Bool. So the code is expanded to
myArray.exists((x : Int) => x < 0)
In your case you should write:
myArray.forall( _ % 2 != 0)
An alternative would be
def xyz(n: Int) = n % 2 == 0
myArray.forall(!xyz(_))
A better error message would be something like "forall expects a function Int => Bool here". I think that this is not possible due to the existence of implicits in Scala. You can read more about this stuff in Chapter 8 of Martin Oderskys Scala book.
Upvotes: 0