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

时间:2014-12-26 14:11:47

标签: scala

给定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) 时才停止评估我改变了代码?也许使用=>运算符?

如果是这样,我认为存在“空间”成本,但我并不完全理解它。请在答案中包含该主题(如果有的话)。

2 个答案:

答案 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)
}