只想在Haskell中找到一个答案

时间:2014-01-18 19:38:18

标签: haskell fold

当我只想要一个答案时,如何使fold {l,r}终止?

假设我有一个布尔值列表b1,b2,b3,...我希望将它们全部组合在一起。如何让折叠停在第一个真值上?

1 个答案:

答案 0 :(得分:14)

它已经做到了!举个例子,让我们制作一个清单

foo :: [Bool]
foo = [False, False, False, True] ++ repeat False

其中repeat只是创建一个无限列表,如果我们将它加载到GHCi

*Main> foldr (||) False foo
  True

“但是,怎么样?”你可能想知道,Haskell是懒惰的,foldr也是如此。如果你看一下实现,你会发现它创建了类似的东西

 foldr f a [b, c, d, e ... z] == (b `f` (c `f` (... (z `f` a)..)))

请注意,当您评估它时,如果f不需要该右侧,则不会对其进行评估,我们可以忽略列表的其余部分,即使它是无限的。这可以用像Haskell这样的惰性语言来实现,因为我们只在需要时评估它们。

||的情况下,因为它被定义为

True  || _ = True
False || a = a

当左侧为真时,我们停止评估列表。免费短路!

注意,foldl不会共享这个不错的属性,因为它会触及列表的所有元素。这导致了一个很好的经验法则,如果你想要短路/非严格,foldr通常是正确的选择,否则foldl'可能更快。