给定List[Foo]
,我会应用函数f
。
def f(foo: Foo): Option[Boolean]
我写了这个函数体,看看任何 Foo是否评估为Some(true)
。
val optFalse: Option[Boolean] = Some(false)
val foos: List[Foo] = ...
foos.foldLeft(optFalse){
(acc: Option[Boolean], elem: Foo) => {
val isMatch: Option[Boolean] = f(elem)
optionOr(acc)(match) // takes 2 Option[Boolean] and `or`'s them.
}
}
但是,f
方法可能是一项昂贵的操作。我宁愿“短路”:
foos.foldLeft(optFalse){
(acc: Option[Boolean], elem: Foo) => {
if( isTrueOption(acc) ) acc
else {
val isMatch: Option[Boolean] = f(elem)
isMatch
}
}
}
是否有非严格方式折叠整个List[Foo]
,但只有Option[Boolean]
之一等于Some(true)
时才停止评估我改变了代码?也许使用=>
运算符?
如果是这样,我认为存在“空间”成本,但我并不完全理解它。请在答案中包含该主题(如果有的话)。
答案 0 :(得分:1)
目前还不清楚Option
在您的代码中扮演的角色。如果您只是想知道f
返回Some(true)
是否有任何值,这听起来像exists
的一个很好的用例,这是一个短路:
foos.exists{x => Some(true) == f(x)}
如果您需要知道是否有任何f
返回None
,那么显然您需要评估整个列表(至少在它们实际上都是Some
的情况下,这可能是有趣的案例)。
如果它必须是fold
,则fold
是严格的(可以编写非严格折叠,但这不是标准的fold
) 。您可以使用breakable
以更加结构化的方式使用@Peter的解决方案。
答案 1 :(得分:0)
这是你在找什么?
foos.reduce {
case (Some(true), _)=> Some(true)
case (_, x) => f(x)
}