在scala中实现implication逻辑运算符

时间:2012-04-20 16:09:28

标签: scala operators

我想知道是否有可能在scala中实现逻辑含义。 例如:

a implies b

翻译成:

!a || b

其中ab是一些评估为Boolean的表达式。

我最初开始关注,但这是一种错误的方法

  implicit def extendedBoolean(a : Boolean) = new {
    def implies(b : Boolean) = {
      !a || b
    }
  }

因为无论a的值如何,它都会评估ba。正确的解决方案只会在b为真时评估a

2 个答案:

答案 0 :(得分:6)

您想使用call-by-name参数,我相信以下内容应该足够了:

implicit def extendedBoolean(a : Boolean) = new {
    def implies(b : => Boolean) = {
      !a || b
    }
  }

说明:

您必须为b传递一些值,但您不希望评估该表达式; Scala可以自动将表达式转换为不带参数的函数,并计算表达式。然后,如果需要,您的implies运算符将评估该nullary(零参数)函数。

由于您提供的类型签名=> Boolean,编译器知道它可以执行此转换。这个post更详细地解释了,但仅仅它的标题是对正在发生的事情的一个非常好的解释:"Automatic Type-Dependent Closure Construction"

Scala的这个功能使人们能够编写控件结构,可能就像使用其他语言的宏编写它们一样容易。观察他们使用两个call-by-name参数重新实现while循环的容易程度:一个用于条件参数,一个用于body。

object TargetTest2 extends Application {
  //type signature not too terribly mysterious
  def whileLoop(cond: => Boolean)(body: => Unit): Unit =
    if (cond) {
      body
      whileLoop(cond)(body)
    }

  //about as easy to use as a plain-old while() loop
  var i = 10
  whileLoop (i > 0) {
    println(i)
    i -= 1
  }
}

答案 1 :(得分:4)

您希望b成为必须评估的函数。这样,只有实际访问它才会被评估。

您可以通过将其类型更改为=> Boolean来执行此操作,这意味着在不需要任何输入的情况下评估为Boolean的内容。

implicit def extendedBoolean(a: Boolean) = new {
  def implies(b: => Boolean) = {
    !a || b
  }
}

以下是如何使用它:

scala> true implies { println("evaluated"); true }
evaluated
res0: Boolean = true

scala> false implies { println("evaluated"); true }
res1: Boolean = true

请注意,当atrue时,会评估b(打印“已评估”)。但是当afalse时,它不会被评估(没有打印)。