当我只想要一个答案时,如何使fold {l,r}终止?
假设我有一个布尔值列表b1,b2,b3,...我希望将它们全部组合在一起。如何让折叠停在第一个真值上?
答案 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'
可能更快。