
This may be a stupud question, but how to make I/O in Haskell really lazy? Here is a simple program: ==== module Main where import System.IO import Foreign import Data.Word import Data.Char s2c :: String -> [Word8] s2c s = map (fromIntegral . ord) s sendstr :: Handle -> String -> IO Int sendstr h s = do let c = s2c s ln = length c allocaBytes ln $ \buf -> do pokeArray buf c hPutBuf h buf ln return ln main = do hSetBuffering stdout NoBuffering l1 <- sendstr stdout "abcde\n" l2 <- sendstr stdout "defghij\n" putStrLn $ "sent " ++ (show l2) ++ " bytes" putStrLn $ "sent " ++ (show l1) ++ " bytes" ==== It prints: abcde defghij sent 8 bytes sent 6 bytes i. e. the first string is output first although the result from that output (how many bytes sent) is needed second. What is desired is to have the IO actions perform as their results are needed. I am assuming some knowledge that those actions have only limited scope of side effects (e. g. order of outputs within a window is significant, but order of appearance of those windows on the screen may not be). I see some way to do this by writing regular non-monadic Haskell stuff, representing each side effects scope (i. e. where ordering of actions is necessary) with its own instance of an I/O like monad (but runnable from an outside non-monadic code), and then using unsafePerformIO as needed. But there may be some framework already developed (albeit with unsafePerformIO, but hiding it from application developers). Any ideas, pointers? Thanks Dimitry

On Mon, 2005-11-28 at 07:27 -0500, Dimitry Golubovsky wrote:
This may be a stupud question, but how to make I/O in Haskell really lazy?
What is desired is to have the IO actions perform as their results are needed. I am assuming some knowledge that those actions have only limited scope of side effects (e. g. order of outputs within a window is significant, but order of appearance of those windows on the screen may not be). I see some way to do this by writing regular non-monadic Haskell stuff, representing each side effects scope (i. e. where ordering of actions is necessary) with its own instance of an I/O like monad (but runnable from an outside non-monadic code), and then using unsafePerformIO as needed. But there may be some framework already developed (albeit with unsafePerformIO, but hiding it from application developers).
Any ideas, pointers?
unsafeInterleaveIO http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html... Duncan

On Mon, Nov 28, 2005 at 07:27:44AM -0500, Dimitry Golubovsky wrote:
Any ideas, pointers?
unsafeInterleaveIO does what you want. -- David Roundy http://www.darcs.net

Am Montag, 28. November 2005 13:27 schrieb Dimitry Golubovsky:
[...]
What is desired is to have the IO actions perform as their results are needed. I am assuming some knowledge that those actions have only limited scope of side effects (e. g. order of outputs within a window is significant, but order of appearance of those windows on the screen may not be). I see some way to do this by writing regular non-monadic Haskell stuff, representing each side effects scope (i. e. where ordering of actions is necessary) with its own instance of an I/O like monad (but runnable from an outside non-monadic code), and then using unsafePerformIO as needed. But there may be some framework already developed (albeit with unsafePerformIO, but hiding it from application developers).
Be very careful with unsafePerformIO. When using it, compiler optimizations are likely to change the semantics of your program. In my diploma thesis, I developed a framework for "lazy execution", based on two special monads. First, I implemented these monads on top of unsafePerformIO. Then I had to discover that it was practically impossible to make this safe but that it was possible to implement these monads on top of unsafeInterleaveIO which I did then.
Any ideas, pointers?
You might want to have a look at my thesis. Alas, it's written in German but maybe the Haskell code it contains is useful for you. It can be downloaded via http://www.informatik.tu-cottbus.de/~jeltsch/diplomarbeit/. Chapter 4 is the "lazy execution" part.
Thanks
Dimitry
Best wishes, Wolfgang
participants (4)
-
David Roundy
-
Dimitry Golubovsky
-
Duncan Coutts
-
Wolfgang Jeltsch