Haskell中的短路(&&)

时间:2009-11-22 14:52:21

标签: haskell boolean combinators

一个一直困扰我的快速问题。 Haskell是否在返回布尔值的函数中执行所有等价测试,即使返回false值也是如此?

例如

f a b = ((a+b) == 2) && ((a*b) == 2)

如果第一个测试返回false,它会在&&之后执行第二次测试吗?或者Haskell是否懒得不去做并继续前进?

4 个答案:

答案 0 :(得分:19)

应该像其他语言一样短路。它在前奏中定义如下:

(&&)                    :: Bool -> Bool -> Bool
True  && x              =  x
False && _              =  False

因此,如果第一个参数为False,则永远不需要评估第二个参数。

答案 1 :(得分:5)

就像马丁所说,懒惰评估的语言永远不会评估任何不需要立即获得价值的东西。在像Haskell这样的懒惰语言中,您可以免费获得短路。在大多数语言中,||和&&并且必须专门为语言构建类似的操作符,以便对它们进行短路评估。但是,在Haskell中,懒惰的评估使得这不必要。你可以定义一个自己短路的功能:

scircuit fb sb = if fb then fb else sb

此函数的行为与逻辑“或”运算符类似。这是如何||在Haskell中定义:

True  || _ = True
False || x = x

所以,为了给你问题的具体答案,没有。如果是||的左侧是的,右手边从未被评估过。您可以将两个和两个放在一起用于“短路”的其他操作员。

答案 2 :(得分:1)

懒惰评估意味着在真正需要之前不评估任何内容。

答案 3 :(得分:1)

一个简单的测试来“证明”Haskell DO 有短路,正如 Caleb 所说。

如果您尝试对无限列表进行求和,则会出现堆栈溢出:

GiftCard

但是如果你运行例如DOMAIN_EVENT_ENTRY(逻辑或)在无限列表中,很快就会得到结果,因为短路:

Prelude> foldr (+) 0 $ repeat 0
*** Exception: stack overflow