我的猜測是因爲「懶惰的評價」。
請注意,您不會返回任何內容。換句話說,「迴歸」還沒有被質疑(沒有回報),也沒有用。在return
聲明中,您並不處於「monadic」環境中。因此沒有理由評估它,因此您只需傳遞「調用樹」即可。
換句話說,它仍然在「調用樹」,直到有人想要拿起它。
對於第二種情況,將調用trace
是微不足道的。 monad被執行直到達到「return
」,並且在達到return
之前,將採取所有必要的操作,包括在需要時執行調試信息。
實施例ghci
:
$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> import Debug.Trace
Prelude Debug.Trace> do return (trace "debug message 1"())
Prelude Debug.Trace> do trace "debug message 2" (return())
debug message 2
同樣爲runhaskell
。如果你寫了這兩種方案:
program1.hs
:
import Debug.Trace
main = do return (trace "debug message 1"())
program2.hs
:
import Debug.Trace
main = do
trace "debug message 2" (return())
然後在控制檯上寫着:
$ runhaskell program1.hs
$ runhaskell program2.hs
debug message 2
$
不過,若你寫一個IO Bool
(因此有返回值)和您以後使用該值,則跟蹤將被執行,例如:
testFun :: IO Bool
testFun = do
trace "foo" $ return $ trace "Hello" True
main :: IO()
main = do
b <- testFun
print b
這將導致:
$ runhaskell program3.hs
foo
Hello
True
$
如果您但是省略了print b
,把return()
相反,Haskell有在返回什麼沒有興趣,因此不打印跟蹤:
testFun :: IO Bool
testFun = do
trace "foo" $ return $ trace "Hello" True
main :: IO()
main = do
b <- testFun
return() --we ran `testFun` but are not interested in the result
結果是:
$ runhaskell program4.hs
foo
$
如果我翻轉訂單,但同樣的事情發生雖然。 'main =執行trace「debug message 2」(return());返回(跟蹤「調試消息1」())' – CMCDragonkai 2015-02-23 12:18:55
@CMCDragonkai:如果我在'ghci'中運行它,第二次,它打印調試消息。它不在此上下文中打印的原因是因爲它放在return語句之後。但是,如果您執行「do trace」調試消息2「(return())」,它將打印調試消息。 – 2015-02-23 12:19:38
用'runhaskell'運行。 – CMCDragonkai 2015-02-23 12:20:15