How to use / refer to the negation of a boolean function in Scala?

I'm trying to use the negation of a boolean function in Scala, such as:

def someFunction(x: Set, p: Int => Boolean): Boolean = 
    someOtherFunction(x, !p)

But I get the error:

 value unary_! is not a member of Int => Boolean

How can I refer to the negation of p?


Solution 1:

The negation of p is a function that applies p to its argument and negates the result.

x => !p(x)

If you want to be able to write !p or p && q you can use this library, which pimps functions that return a bool with various logical operators.

Solution 2:

Shortest negation of p: !p(_)

When you apply the predicate p as an argument to another function:

  • p or p(_) are abbreviations of the lambda expresion: (x) => p(x)
  • !p(_) is an abbreviation of the lambda expresion: (x) => !p(x) and with only !p the compiler gets lost.

For example, using a Set of integers (try it on a Scala worksheet):

  def someOtherFunction (x: Set[Int], p: Int => Boolean):Boolean = x.forall(p)
  def someFunction(x: Set[Int], p: Int => Boolean): Boolean =
    someOtherFunction(x, !p(_))

  val x = Set(1,2,3)
  var p: Int => Boolean = (_ > 0)
  //_ > 0 is an abbreviaton of (x) => x > 0

  someFunction(x, p)        //false
  someOtherFunction(x, p)   //true

  p = _ > 1
  someFunction(x, p)        //false
  someOtherFunction(x, p)   //false

  p = _ > 3
  someFunction(x, p)        //true
  someOtherFunction(x, p)   //false
  println

Solution 3:

Another way to solve it without the use of an anonym function is to define a concrete function for this task.

def even(x:Int):Boolean = x%2==0
def not(f: Int => Boolean): Int => Boolean = !f(_)
def odd = not(even)
odd(1) // true
odd(2) // false

You can also define ! yourself

def even: Int => Boolean = _%2==0
implicit def bangy(f: Int => Boolean) = new { def unary_! : Int => Boolean = !f(_) }
def odd = !even
odd(1) // true
odd(2) // false

but this only seems to works for functions of type Int=>Boolean, and not (Int)=>Boolean. The not(even) solution works with both.