Scala谓词组成

时间:2019-03-30 08:54:55

标签: scala

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))

3 个答案:

答案 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 ⇒ BooleanPredicate的隐式转换,以支持所需的操作。像这样:

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)

它不是标准库的一部分,但是如果您只需要简单的表达式,则可以:

  1. 使用Java版本,可能使用句法糖的扩展方法,例如p1 || p2而不是p1.or(p2)
  2. 使用以下几种简单方法滚动自己的case class Predicate[-A](p: A => Boolean)

    def ||[B <: A](other: Predicate[B]): Predicate[B] = ???