Lazy IO in haskell: How to return a lazy list that is generated by some blocked IO?
haskell, lazy-evaluation
Solution
This can be accomplished with the `unsafeInterleaveIO` function from `System.IO.Unsafe`. Your `getText` function then becomes
getText = do
c <- getChar
s <- unsafeInterleaveIO $ getText
return (c : s)
Abstracting slightly, we can get a function to generalize this behaviour
lazyDoIO :: IO a -> IO [a]
lazyDoIO act = unsafeInterleaveIO $ do
now <- act
rest <- lazyDoIO act
return (now : rest)
getText = lazyDoIO getChar
Most Haskellers would cringe at doing this, however. If you want to do incremental stream processing of `IO` generated data, it would be much safer to use a library like `Pipes` or `Conduits`.
Problem
``` getText = do c <- getChar s <- getText return (c : s) main = do s <- getText putStr s ``` What I expect to see is that the input line being echoed each time after I press 'Enter'. But nothing is echoed ... (I know that this is a infinite loop) It seems that it won't "`return`" until all the "IO" above it are performed. ... However, the following code: ``` main = do s <- getContents putStr s ``` It display the line immediately after input. Given the function `getChar`, can I write a `getText` that behaves like `getContents`?