這段代碼:
import Data.Foldable
import Debug.Trace
factors :: [Bool]
factors = [True, True, False, True, True, True, True, True]
andy :: Bool -> Bool -> Bool
andy False _ = False
andy True False = False
andy True True = True
tandy :: Bool -> Bool -> Bool
tandy a b = let c = a `andy` b in trace (show a " & " show b " = " show c) c
wonder :: Bool
wonder = foldl tandy True factors
當我評估時這樣說wonder:
True & True = True
True & True = True
True & False = False
False & True = False
False & True = False
False & True = False
False & True = False
False & True = False
但我寧愿它早點停止。我已經嘗試了所有可以想象的東西來代替foldl和&&代替,andy但它似乎從來沒有得到暗示。
在我看來,該行andy False _ = False并沒有邀請編譯器評估第二個引數。我沒有強迫任何嚴格。這是怎么回事?甚至 C 也可以做得更好。
uj5u.com熱心網友回復:
tandy在兩個引數中都是嚴格的,即使andy不是。這是因為追蹤。您要求它在對 的呼叫中顯示兩個輸入trace,因此它必須評估兩個引數。
考慮“tandy2”:
tandy2 :: Bool -> Bool -> Bool
tandy2 False _ = trace ("False & anything = False") False
tandy2 True b = trace ("True & " show b " = False") b
與其在跟蹤程序中盲目地評估兩個論點,不如只評估它原本會評估的相同論點。這使得它實際上反映了與它相同的嚴格屬性andy。
嘗試使用tandy2with foldr,你會看到它一碰到False.
$ ghci
GHCi, version 9.2.1: https://www.haskell.org/ghc/ :? for help
ghci> import Debug.Trace
ghci> let tandy2 False _ = trace ("False & anything = False") False ; tandy2 True b = trace ("True & " show b " = False") b
ghci> foldr tandy2 True []
True
ghci> foldr tandy2 True [True]
True & True = False
True
ghci> foldr tandy2 True [True, False]
False & anything = False
True & False = False
False
ghci> foldr tandy2 True [True, False, True]
False & anything = False
True & False = False
False
你去吧。False它從不多次評估分支。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427252.html
