java谓词接口提供了一种or
方法,该方法用于组合多个谓词。示例:
Predicate<Integer> p1;
Predicate<Integer> p2;
Predicate<Integer> p2 = p1.or(p2)
由于scala没有Predicate
接口,但为此目的使用Function1[A, Boolean]
是什么?最好不要使用外部库。
我尽量避免以下情况:
val p1: (A => Boolean)
val p2: (A => Boolean)
val p3: (A => Boolean) = (a => p1(a) || p2(a))
答案 0 :(得分:9)
您可以在隐式值类中将Predicate
功能提供为
implicit class Predicate[A](val p1: A => Boolean) extends AnyVal {
def or[B >: A](p2: B => Boolean) = (a: A) => p1(a) || p2(a)
}
然后做
val gtOne = (x: Int) => x > 1
val ltMinusOne = (x: Int) => x < -1
val absGtOne = gtOne or ltMinusOne
absGtOne(-2) // true
absGtOne(0) // false
absGtOne(2) // true
答案 1 :(得分:3)
您可以提供从A ⇒ Boolean
到Predicate
的隐式转换,以支持所需的操作。像这样:
implicit class Predicate[A](val p: A ⇒ Boolean) extends AnyVal {
type Predicate[A] = A ⇒ Boolean
def unary_! = (a: A) ⇒ !p(a)
def ==[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) == x(a)
def !=[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) != x(a)
def ||[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) || x(a)
def &&[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) && x(a)
def ^[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) ^ x(a)
def |[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) | x(a)
def &[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) & x(a)
}
这以相同的语义实现Boolean
中可用的所有方法,例如Predicate.&&
仅在第一个谓词评估为true
时才评估第二个谓词,而Predicate.|
将始终评估两个谓词。
答案 2 :(得分:2)
它不是标准库的一部分,但是如果您只需要简单的表达式,则可以:
p1 || p2
而不是p1.or(p2)
。 使用以下几种简单方法滚动自己的case class Predicate[-A](p: A => Boolean)
:
def ||[B <: A](other: Predicate[B]): Predicate[B] = ???