选项的非严格评估[布尔值]



给定一个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)
}

最新更新