且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

是否可以在不使用`unsafeIO`的情况下使用`sequence`的懒惰版本?

更新时间:2022-10-14 22:47:43

否。



如果您有类型 IO a 的内容,则无法获取 IO 块,则会从 a 之外的任何信息。从概念上讲,可以将 act :: IO a 定义为一组任意复杂的动作,然后根据对系统随机数发生器的调用产生一个结果。

unsafeInterleaveIO 的整个目的是执行你所要求的,如果没有它,就无法完成。


If I have a possibly infinite list of IO-monads, and I am guaranteed that their sequential execution will not be affected by other IOs, can I somehow make it lazily sequenced (evaluated)?

To clarify my point, here is some pseudo-Haskell code demonstrating what I had in mind:

main = do
    inputs <- sequence . repeat $ getLine -- we are forever stuck here
    mapM_ putStrLn inputs -- not going to run

Now, I know that in the particular example above, we can just use getContents to get the effect I want

main = do
    inputs <- return . lines =<< getContents
    mapM_ putStrLn inputs

but in my application the IO monads are not getLine but an external function get1 :: IO (Maybe Record). However, this actually brings my point, because apparently getContents internally uses unsafeIOs to achieve this lazy-effect. My question is, is that necessary? (If you are interested in what exactly I want to do, please refer to this question.)

Just to bell the cat: No.

If you have something of type IO a, there is no way to get any information out of that a without fully executing that IO block. Conceptually, that act :: IO a could be defined as an arbitrary complicated set of actions, followed by then just producing a result dependent on a call to the system random number generator.

The entire purpose of unsafeInterleaveIO is perform what you're asking, and it can't be done without it.