IO计算顺序

Ser*_*nin 3 haskell

我已经学习了Haskell一段时间了,但IO monad还是吓到了我.我有一个代码

main = do
    putStrLn "First computation starts"
    let firstResult = foo -- foo is a pure function
    putStrLn "Second computation starts"
    let secondResult = bar foo -- bar is too pure function
    writeFile secondResult 
Run Code Online (Sandbox Code Playgroud)

然后看看"First computation starts" "Second computation starts"程序会做什么.

我知道存在laisy计算,并且在writeFile执行时真正开始计算.我试图增加严格性

    main = do
    putStrLn "First computation starts"
    let !firstResult = foo -- foo is a pure function
    putStrLn "Second computation starts"
    let !secondResult = bar foo -- bar is too pure function
    writeFile secondResult 
Run Code Online (Sandbox Code Playgroud)

什么都没发生

好吧,也许让表达式只是同义词并由编译器交换?我尝试将函数转换为IO

main = do
putStrLn "First computation starts"
!firstResult <- return (foo) -- foo is a pure function
putStrLn "Second computation starts"
!secondResult <- return (bar foo) -- bar is too pure function
writeFile secondResult 
Run Code Online (Sandbox Code Playgroud)

然而,结果与上面相同,对我来说还不清楚.

Wal*_*inz 5

如果你想确定某些东西已被评估,那么deepseq就是你的朋友.你必须实现NFData任何目标foo,但这通常很容易实现.main然后你会成为

main = do
  putStrLn "First computation starts"
  firstResult <- return $!! foo
  putStrLn "Second computation starts"
  secondResult <- return $!! bar foo
  writeFile secondResult 
Run Code Online (Sandbox Code Playgroud)