我可能不太了解IO monad。
如果我编写一个预计会运行数月的应用程序,同时记录其进度,IO monad是否会将所有日志信息保存在RAM中直到结束?
在IO Inside上的博客中,Haskell将世界建模为
main :: RealWorld -> ((), RealWorld)
以便在执行代码的Haskell部分期间不会发生IO,但仅在应用程序从main
返回时才会发生。
我可能完全误解了这一点。有人可以解释何时 Haskell实际上做IO?
答案 0 :(得分:8)
IO monad会将所有日志信息保存在RAM中直到结束吗?
没有。您不应该将“IO monad”视为执行操作的内容。它只是表示命令式程序的数学方式。原始命令式程序是getChar
之类的东西; >>=
用于将两个程序粘合在一起形成一个更大的命令式程序。 IO monad是所有命令式程序的集合。
考虑诸如
之类的程序main = putStr "Hello, " >> putStrLn "world!"
这意味着:main
是执行程序putStr "Hello, "
的程序,完成后,执行程序putStrLn "world!"
。除了指令指针之外,Haskell解释器或编译程序不需要将任何状态保存在内存中,即“我们在哪里,以及我们接下来要执行什么”。
RealWorld -> ((), RealWorld)
比喻可能让你感到困惑,因为它似乎意味着外部世界的状态转变为一个必须全部计算的新状态,之后可以更新世界以反映计算结果州。这根本不是什么。 Haskell维基警告说:
关于IO的以下故事是不正确的,因为它无法解释IO的一些重要方面(包括交互和并发)。
答案 1 :(得分:4)
IO monad会将所有日志信息保存在RAM中直到结束吗?
没有。假设您正在使用合理的日志记录策略。
当程序要求结果时,Haskell会执行IO;大多数行动都是立即行动的(例外是惰性文件输入库,在程序使用数据之前不必读取文件)。