Curried函数评估所有参数

时间:2013-05-22 23:53:17

标签: scala

我试图找出为什么我的curried功能以下列方式运行。我构建了函数确保采用更多函数方法而不是多个if-then语句来完成同样的事情。

我发现今天有一个bug会运行一些测试,如果第一个中的条件确保功能,例如确保(contents.hasNext&& acc!= null)为true,错误条件或第二个争论仍然会被评估并成为重写函数。

我可以解决这个问题,如果我简单地改变这个:确保(contents.hasNext)到这个:确保(contents.hasNext&& acc == null)但我正在努力为什么会发生这种情况。

是否有更明显(或更好)的解决方案?

  def ensure[T](f: => Boolean)(truth: => T, lie: T) = if (f) truth else lie


  def lines(): Stream[String] = {
    def matchLine(text: String, acc: String): Stream[String] = text match {
      ...
      case NewLine(string) =>
        ensure(contents.hasNext && acc != null)(acc +: matchLine(contents.next, string),
          ensure(contents.hasNext)(matchLine(contents.next, string), acc +: string +: empty))
      ...
    }
    ensure(contents.hasNext)(matchLine(contents.next, null), empty)
  } 

1 个答案:

答案 0 :(得分:3)

(truth: => T, lie: T)

这意味着,每次truth在您的函数中使用时(仅当时),将评估为truth参数指定的表达式,而lie将完全执行一旦你的函数开始执行之前。换句话说:truth按名称传递,lie则不传递。为了实现你想要的行为,你需要通过名称传递两个(另一方面,通过名称传递条件并不是必需的,因为在所有情况下它将在函数的开头只被评估一次):

ensure[T](f: Boolean)(truth: => T, lie: => T) = if (f) truth else lie

那就是说,我不同意用一个基本上是if-then-else包装的函数替换if-then-else表达式,使你的代码更具功能性。