Dear Haskellers, Can you tell me how to force Haskell to output the results in a `lazy' way? Consider, for example, the program main = putStr (concat ["\n min1 = ", show min1, "\n min2 = ", show min2, "\n" ] ) where min1 = minimum [1 .. 10 ] :: Integer min2 = minimum [1 .. (10^10)] :: Integer I do not know whether the effect is due to implementation. And I `make'-run the program under GHC-6.2.2-pre by commanding ghc -O --make Main ./a.out This prints min1 = 1 and hangs silently -- probably, because min2 takes long to compute. But why does not it print immediately min1 = 1 min2 = ? This is for the first time in my practice that a `lazy' printing is essential. The above example is contrived. The real example is a program that searches for the proof and accumulates a certain ptrace :: ProofTrace, type ProofTrace = [Step] The first steps are performed easily, and also they are informative. So, the user should see their results immediately -- when one applies (show ptrace). The whole proof may take long, the last steps in ptrace may be ready after a very long time. And Haskell just holds until the whole ptrace is ready, which is annoying. Copy, please, the answer to mechvel@botik.ru With kind regards, ----------------- Serge Mechveliani mechvel@botik.ru
Dear Haskellers,
Can you tell me how to force Haskell to output the results in a `lazy' way? [..] main = putStr (concat ["\n min1 = ", show min1, "\n min2 = ", show min2, "\n" ] ) [..] This prints min1 = 1
and hangs silently -- probably, because min2 takes long to compute. But why does not it print immediately
min1 = 1 min2 =
Haskell is outputting lazily, but by default stdout is set to LineBuffering - for efficiency, a line is only written to stdout once it is complete. Try adding "\n" to the end of the "min2 =" line to see what I mean. To get the behaviour you describe, add import IO and hSetBuffering stdout NoBuffering >> to the start of your main function. --KW 8-) -- Keith Wansbrough <kw217@cl.cam.ac.uk> http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory.
To my request
Can you tell me how to force Haskell to output the results in a `lazy' way? [..] main = putStr (concat ["\n min1 = ", show min1, "\n min2 = ", show min2, "\n" ] ) [..] This prints min1 = 1
and hangs silently -- probably, because min2 takes long to compute. But why does not it print immediately
min1 = 1 min2 =
Keith Wansbrough <kw217@cl.cam.ac.uk> writes
Haskell is outputting lazily, but by default stdout is set to LineBuffering - for efficiency, a line is only written to stdout once it is complete. Try adding "\n" to the end of the "min2 =" line to see what I mean. To get the behaviour you describe, add import IO and hSetBuffering stdout NoBuffering >> to the start of your main function.
( and what if it also aplies writeFile "log" ? ) Thank you. It helps with the contrived examples. But I cannot do a real example, so far: --------------------------------------------------------------- module Main where import IO import Test (test) main = hSetBuffering stdout NoBuffering >> test ------------------------------- type ProofTrace = [ProofTraceStep] ... instance Show ProofTraceStep where showsPrec _ step = ("\n-----------------------------\n"++) . sho step where sho (ProveGoal g rc) = ("Proving the goal\n " ++) . shows (goalIndex g) . ("\nwith the formula\n " ++) . shows (goalFormula g) . ("\ngiven the resource "++) . shows rc sho ... = ... --------------------------------------------------------------- The trace data field is ptrace :: ProofTrace -> ProofTrace , it is accumulated during the program like this: \ ... g ptrace -> ptrace . ((BranchProved [g]) :) It prints out by show (ptrace []), via the above Show instance for ProofTraceStep. Of course, this information may be not sufficient, and probably, I need further experimenting and investigation. Copy, please, the answer, if any, to mechvel@botik.ru ----------------- Serge Mechveliani mechvel@botik.ru
Serge D. Mechveliani wrote:
Haskell is outputting lazily, but by default stdout is set to LineBuffering - for efficiency, a line is only written to stdout once it is complete. Try adding "\n" to the end of the "min2 =" line to see what I mean. To get the behaviour you describe, add import IO and hSetBuffering stdout NoBuffering >> to the start of your main function.
( and what if it also aplies writeFile "log" ? )
Streams which are associated with files are fully-buffered by default, so writeFile would generate the output in blocks. If you wanted to change the buffering, you would have to open the file yourself so that you could get at the descriptor, e.g. handle <- openFile "log" AppendMode hSetBuffering handle NoBuffering hPutStr handle string hClose handle -- Glynn Clements <glynn.clements@virgin.net>
participants (3)
-
Glynn Clements -
Keith Wansbrough -
Serge D. Mechveliani