IO计算顺序

3

我学习了一些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 

看到 "第一个计算开始""第二个计算开始",然后程序将继续执行。

我知道有惰性计算,真正的计算是在执行 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 

什么都没发生

也许让表达式只是编译器中的同义词和交换?我尝试将函数转化为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 

尽管结果与之前相同,但对我来说仍然不清楚。
1个回答

5
如果您想确保某个东西已经被评估,deepseq 是您的好帮手。您将不得不为任何 foo 实现 NFData,但这通常很容易做到。您的 main 将变成:
main = do
  putStrLn "First computation starts"
  firstResult <- return $!! foo
  putStrLn "Second computation starts"
  secondResult <- return $!! bar foo
  writeFile secondResult 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接