Comment utiliser / se référer à la négation d'une fonction booléenne dans Scala?

J'essaie d'utiliser la négation d'une fonction booléenne dans Scala, telle que:

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

Mais je reçois l'erreur:

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

Comment puis-je me référer à la négation de p?

37
demandé sur Emre Sevinç 2012-10-02 01:48:32

3 réponses

La négation de p est une fonction qui applique p à son argument et annule le résultat.

x => !p(x)

Si vous voulez pouvoir écrire !p ou p && q Vous pouvez utiliser cette bibliothèque , qui pimps fonctions qui renvoient un bool avec différents opérateurs logiques.

53
répondu Kim Stebel 2012-10-01 21:50:31

Négation la plus courte de p: !p(_)

Lorsque vous appliquez le prédicat p comme argument d'une autre fonction:

  • p ou p(_) sont des abréviations de la lambda expression: (x) => p(x)
  • !p (_) est une abréviation de l'expression lambda: (x)=>!p(x) et avec !p le compilateur se perd.

Par exemple, en utilisant un ensemble d'entiers (essayez-le sur une feuille de calcul Scala):

  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
14
répondu carlos_lm 2014-09-24 19:04:17

Une autre façon de le résoudre sans l'utilisation d'une fonction anonyme est de définir une fonction concrète pour cette tâche.

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

Vous pouvez également définir ! vous-même

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

Mais cela ne semble fonctionner que pour les fonctions de type Int= > Boolean, et non (Int)=>Boolean. La solution not (even) fonctionne avec les deux.

3
répondu Istador 2012-10-06 16:49:28