Scala Curried函数计算所有参数
我试图弄明白为什么我的curried函数按以下方式运行。我构建函数确保采用更具功能的方法,而不是多个if-then语句来完成相同的任务 我今天发现了一个bug,它将运行一些测试,如果第一个sure函数中的条件(例如sure(contents.hasNext&&acc!=null)为真,则仍然会计算假条件或第二个参数,并成为覆盖函数 如果我简单地将以下内容更改为:sure(contents.hasNext),我就可以解决这个问题:sure(contents.hasNext&&acc==null),但我仍在苦苦思索为什么会发生这种情况 有没有更明显(或更好)的解决方案Scala Curried函数计算所有参数,scala,Scala,我试图弄明白为什么我的curried函数按以下方式运行。我构建函数确保采用更具功能的方法,而不是多个if-then语句来完成相同的任务 我今天发现了一个bug,它将运行一些测试,如果第一个sure函数中的条件(例如sure(contents.hasNext&&acc!=null)为真,则仍然会计算假条件或第二个参数,并成为覆盖函数 如果我简单地将以下内容更改为:sure(contents.hasNext),我就可以解决这个问题:sure(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)
}
这意味着每次在函数中使用truth
时(并且只有在那时),将对truth
参数给出的表达式求值,而lie
将在函数开始执行之前执行一次。换句话说:truth
是通过名字传递的,lie
不是。为了实现您想要的行为,您需要按名称传递这两个条件(另一方面,按名称传递条件并不是真正必要的,因为在所有情况下,在函数开始时它都会被精确地计算一次):
也就是说,我不同意用基本上是if-then-else包装器的函数替换if-then-else表达式会使代码更具功能性
这意味着每次在函数中使用truth
时(并且只有在那时),将对truth
参数给出的表达式求值,而lie
将在函数开始执行之前执行一次。换句话说:truth
是通过名字传递的,lie
不是。为了实现您想要的行为,您需要按名称传递这两个条件(另一方面,按名称传递条件并不是真正必要的,因为在所有情况下,在函数开始时它都会被精确地计算一次):
也就是说,我不同意用基本上是if-then-else包装的函数替换if-then-else表达式会使代码更具功能。如果您真的想计算一个条件并调用两个可能的按名称函数之一(一个为true,另一个为false),您应该查看
Scalaz
。它有一个fold
方法,该方法被赋予布尔值,以精确执行您在这里所做的操作。如果您真的想计算一个条件并调用两个可能的按名称函数(一个为true,另一个为false)中的一个,您应该查看Scalaz
。它有一个fold
方法,该方法将pumped设置为boolean,以完成您在这里所做的事情。
(truth: => T, lie: T)
ensure[T](f: Boolean)(truth: => T, lie: => T) = if (f) truth else lie