最近一直困擾我的一個簡單問題。 Haskell是否會在返回布爾值的函數中執行所有等價測試,即使返回一個假值?Haskell短路(&&)
例如
f a b = ((a+b) == 2) && ((a*b) == 2)
如果第一測試返回false,其將執行&&
之後的第二測試?還是Haskell懶得不行,繼續前進?
最近一直困擾我的一個簡單問題。 Haskell是否會在返回布爾值的函數中執行所有等價測試,即使返回一個假值?Haskell短路(&&)
例如
f a b = ((a+b) == 2) && ((a*b) == 2)
如果第一測試返回false,其將執行&&
之後的第二測試?還是Haskell懶得不行,繼續前進?
應該像其他語言一樣短路。它的定義是這樣的前奏:
(&&) :: Bool -> Bool -> Bool
True && x = x
False && _ = False
因此,如果第一個參數是假的第二永不需要進行評估。
懶惰的評價意味着,只有真正需要評價纔會評價。
就像馬丁說的那樣,懶惰評估的語言從來沒有評估任何價值不是馬上需要的東西。像Haskell這樣的懶惰語言,你會免費獲得短路。在大多數語言中,||和& &和類似的運營商必須專門建立的語言,以便他們進行短路評估。但是,在Haskell中,懶惰的評估使得這是不必要的。您可以定義短路甚至自己的函數:
scircuit fb sb = if fb then fb else sb
此功能將表現就像邏輯「或」操作。這裏是||在Haskell中定義:
True || _ = True
False || x = x
因此,要給你具體的答案你的問題,沒有。如果||的左側是真的,右手邊從未被評估過。您可以將其中兩個和兩個「短路」的其他運營商放在一起。
在列表解析的情況下,這也是一樣的嗎? – 2009-11-22 15:11:23
'短路'說的不正確。你根本不知道這些值是否被評估過,因爲你沒有辦法證明它沒有副作用,但是除非需要,否則它們不太可能。 – Dario 2009-11-22 15:14:53
我認爲它和C++一樣:語言表示右邊沒有得到評估。但是,當然,如果編譯器可以告訴它沒有任何副作用,它可以評估它 - 而且一些C++編譯器可以這樣做,因爲條件分支很貴。 – 2009-11-22 15:28:05