4

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

a implies b

翻译成:

!a || b

whereab是一些计算结果为 的表达式Boolean

我最初是从以下开始的,但这是错误的方法

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

因为它将a同时b评估a. 正确的解决方案只会评估b何时a为真。

4

2 回答 2

7

您想使用按名称调用的参数,我相信以下内容就足够了:

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

解释:

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

由于您提供的类型签名,编译器知道它可以执行此转换,=> Boolean. 这篇文章更详细地解释了,但仅它的标题就很好地概括了正在发生的事情:“Automatic Type-Dependent Closure Construction”

Scala 的这一特性使人们能够编写控制结构,可能就像使用其他语言中的宏来编写它们一样容易。观察他们使用两个按名称调用的参数重新实现 while 循环的难易程度:一个用于条件,一个用于主体。

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
  }
}
于 2012-04-20T16:15:46.387 回答
4

您想要创建b一个必须评估的函数。这样,只有在实际访问时才会对其进行评估。

您可以通过将其类型更改为 来做到这一点=> Boolean,这意味着Boolean无需任何输入即可评估为 a 的东西。

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

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

于 2012-04-20T16:13:48.293 回答