此代码(从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_不是懒惰的。 –