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`?

Original source

Related problems