给定一个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)
,就停止评估,而无需我更改的代码?也许使用=>
运算符?
如果是这样,我认为存在"空间"成本,但我并不完全理解它。请在您的答案中也包括该主题(如果有的话)。
目前还不清楚Option
在你的代码中扮演什么角色。如果你只是想找出是否有任何值f
返回Some(true)
,这听起来像是exists
的一个很好的用例,这是短路:
foos.exists{x => Some(true) == f(x)}
如果你需要知道是否有任何f
返回None
,那么显然你需要评估整个列表(至少在它们实际上都是Some
的情况下,这可能是一个有趣的情况)。
如果它必须是fold
,那么fold
是严格的(可以写一个非严格折叠,但这不是标准的fold
)。您可以通过使用 breakable
以更结构化的方式使用 @Peter 的解决方案。
这是你要找的吗?
foos.reduce {
case (Some(true), _)=> Some(true)
case (_, x) => f(x)
}