以下haskell代码中的第一次打印何时发生?

以下haskell代码中的第一次打印何时发生?,haskell,monads,Haskell,Monads,我对f的理解方式简化为(putstrn“1”)>=(\\\->(putstrn“2”)。在应用lambda(从monad中取出)时是否完成了打印操作?有人能告诉我哪一部分在哪个阶段得到评估和执行吗 putStrLn的类型是String->IO(),因此,它进行计算,然后在IO单子中返回一个,,的第二个函数被丢弃,然后只计算第二个putStrLn 命令如下: 1.-putStrLn“1” 2-获得一个()作为结果 3.-\()->putStrLn 2 4.-putStrLn 2 如果不是你想的话,

我对
f
的理解方式简化为
(putstrn“1”)>=(\\\->(putstrn“2”)
。在应用lambda(从monad中取出)时是否完成了打印操作?有人能告诉我哪一部分在哪个阶段得到评估和执行吗

putStrLn
的类型是
String->IO()
,因此,它进行计算,然后在
IO
单子中返回一个
的第二个函数被丢弃,然后只计算第二个
putStrLn

命令如下:

1.-
putStrLn“1”

2-获得一个
()
作为结果

3.-
\()->putStrLn 2

4.-
putStrLn 2


如果不是你想的话,sintaxis不会完全像那样。

假设程序在第3步后崩溃,屏幕上会出现“1”吗?@abhishek正确
do{putStrLn“1”;undefined}
打印
1
然后崩溃。@4castle感谢您的回复。函数
f
在这里计算它的主体并将一个monad返回给main,main将执行该monad。因此,在上述代码中,f将永远不会返回未定义的内部do块,或者
>>
将永远不会成功,因此main将永远不会运行,因此不会发生任何副作用。AFAIU-only-main能够产生副作用?@abhishek由于懒惰,
>
可以返回,而无需评估其任何参数。当最终需要其输出时,它不需要计算第二个参数,直到
putStrLn“1”
完成执行。
IO
monad是专门为保证副作用的计算顺序而设计的。不过,一般来说,Haskell并不保证表达式的哪一部分首先被计算。唯一的保证是它将尽可能地懒惰。
f = do
    putStrLn "1"
    putStrLn "2"

main = f