【问题标题】:When does first print happen in the below haskell code?下面的 haskell 代码中第一次打印是什么时候发生的?
【发布时间】:2017-11-28 12:48:15
【问题描述】:
f = do
    putStrLn "1"
    putStrLn "2"

main = f

我理解f 的方式简化为(putStrLn "1")>>=(\_ -> (putStrLn "2"))。应用 lambda 时打印操作是否完成(将 _ 从 monad 中提升)?有人可以解释一下哪个部分在哪个阶段得到评估和执行?

【问题讨论】:

  • IO monad 是专门为保证副作用动作的评估顺序而设计的。但总的来说,Haskell 并不保证首先计算表达式的哪一部分。唯一的保证是它会尽可能地懒惰。

标签: haskell monads


【解决方案1】:

putStrLnString -> IO () 类型,因此,它进行计算,然后在IO monad 中返回(),因此第二个函数采用(),然后将其丢弃,然后只计算第二个putStrLn

顺序是:

1.- putStrLn "1"

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

3.- \() -> putStrLn 2

4.- putStrLn 2

sintaxis 不会完全像那样,而是让你提出一个想法。

【讨论】:

  • 假设程序在第 3 步后崩溃,屏幕上会出现“1”吗?
  • @abhishek 正确。 do { putStrLn "1"; undefined } 打印 1 然后崩溃。
  • @4castle 感谢您的回复。函数f 在这里评估它的主体并将一个单子返回给 main 执行的 main。所以不会 f 永远不会在上面的代码中返回 do 块或 >> 永远不会成功,因此 main 永远不会运行,因此不会发生副作用。 AFAIU 只有 main 有副作用吗?
  • @abhishek 因为懒惰,>> 可以在不评估其任何参数的情况下返回。当最终需要它的输出时,它不需要评估它的第二个参数,直到 putStrLn "1" 完成执行。
猜你喜欢
  • 2011-05-28
  • 2020-01-29
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
相关资源
最近更新 更多