0

我试图弄清楚为什么我的咖喱函数以下列方式运行。我构建的函数确保采用更多函数方法,而不是多个 if-then 语句来完成相同的事情。

我今天发现了一个错误,它将运行一些测试,如果第一个确保函数中的条件,例如ensure(contents.hasNext && acc != null)为真,则错误条件或第二个参数仍然会被评估并成为覆盖函数。

如果我简单地将其更改为:ensure(contents.hasNext) ,我可以解决问题:ensure(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)
  } 
4

1 回答 1

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 包装器的函数会使您的代码更具功能性。

于 2013-05-23T00:01:00.350 回答