2009-11-22 30 views
16

最近一直困擾我的一個簡單問題。 Haskell是否會在返回布爾值的函數中執行所有等價測試,即使返回一個假值?Haskell短路(&&)

例如

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

如果第一測試返回false,其將執行&&之後的第二測試?還是Haskell懶得不行,繼續前進?

回答

18

應該像其他語言一樣短路。它的定義是這樣的前奏:

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

因此,如果第一個參數是假的第二永不需要進行評估。

+0

在列表解析的情況下,這也是一樣的嗎? – 2009-11-22 15:11:23

+0

'短路'說的不正確。你根本不知道這些值是否被評估過,因爲你沒有辦法證明它沒有副作用,但是除非需要,否則它們不太可能。 – Dario 2009-11-22 15:14:53

+0

我認爲它和C++一樣:語言表示右邊沒有得到評估。但是,當然,如果編譯器可以告訴它沒有任何副作用,它可以評估它 - 而且一些C++編譯器可以這樣做,因爲條件分支很貴。 – 2009-11-22 15:28:05

1

懶惰的評價意味着,只有真正需要評價纔會評價。

5

就像馬丁說的那樣,懶惰評估的語言從來沒有評估任何價值不是馬上需要的東西。像Haskell這樣的懶惰語言,你會免費獲得短路。在大多數語言中,||和& &和類似的運營商必須專門建立的語言,以便他們進行短路評估。但是,在Haskell中,懶惰的評估使得這是不必要的。您可以定義短路甚至自己的函數:

scircuit fb sb = if fb then fb else sb

此功能將表現就像邏輯「或」操作。這裏是||在Haskell中定義:

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

因此,要給你具體的答案你的問題,沒有。如果||的左側是真的,右手邊從未被評估過。您可以將其中兩個和兩個「短路」的其他運營商放在一起。