此代碼(從Learn You A Haskell拍攝):懶惰的評價和IO副作用混亂
main = do putStr "Hey, "
putStr "I'm "
putStrLn "Andy!"
顯然desugars到
main = putStr "Hey, " >>=
(\_ -> putStr "I'm " >>=
(\_ -> putStrLn "Andy!"))
其中,按照我的理解,可以interpretted的話說,「爲了putStrLn「Andy!」我首先需要把STR「我是」,爲了做到這一點,我首先需要把STR「嘿」;
我不同意這種解釋,這是令人討厭的,因爲t他的編譯器顯然不會讓我感到困惑。我對它的問題是,lambda忽略了他們的論點,在懶惰的評估中,這種事情不應該被認可並被短路?
此外,當然,綁定返回一個IO操作,當該IO操作落入主操作時,它會被執行。但是,如何阻止它打印「嘿,安迪!我是」?我懷疑這是綁定正在做的事情。
此外,類型爲「IO()」的IO操作如何攜帶足夠的信息以允許運行時系統打印「嘿,我是安迪!」? IO()與IO()的區別是如何打印「Hello World!」或寫入文件?
考慮另一個,從維基百科頁面單子:
加糖版本:
do
putStrLn "What is your name?"
name <- getLine
putStrLn ("Nice to meet you, " ++ name ++ "!")
脫版本:
putStrLn "What is your name?" >>=
(\_ ->
getLine >>=
(\name ->
putStrLn ("Nice to meet you, " ++ name ++ "!")))
類似這裏的故事。
我想我只需要看到IO的綁定的定義,然後它將全部清楚。如果有人能夠幫助我逐步瞭解程序實際得到評估的方式並找出發生副作用的確切時刻,那麼其他一些有用的東西就會有幫助。
「拉姆達斯忽視他們的論點,在懶惰的評估過程中,這種事情不應該被認爲是短暫的嗎?」你打賭! '(>> =)'的第二個參數在這裏是一個特別懶惰的函數,但是'(>> =)'函數_itself_不是懶惰的。 –