Incomplete output when hPutStr is lifted
Hi, If I compile and run the code below, the file "foo" contains 10 lines of output (as I would expect), but the file "bar" contains just 9 - the final line is missing. If I add a "join", as in the comment, then all 10 lines appear. I don't understand why, completely - my best guess is that it's related laziness and the final result of the fold not being used. However, in that case, I'm worried that the "join fix" isn't guaranteed to work. Please could someone explain what is happening and how I should guarantee that the output is "complete". Thanks, Andrew $ cat test.hs main :: IO() main = do h <- openFile "foo" WriteMode foldM (printer h) 1 [1..10] hClose h h <- openFile "bar" WriteMode foldM (liftM2 (printer h)) (return 1) $ map return [1..10] -- join $ foldM (liftM2 (printer h)) (return 1) $ map return [1..10] hClose h printer :: Handle -> Int -> Int -> IO Int printer h n i = do hPutStr h (show n) hPutStr h ":" hPutStr h (show i) hPutStr h "\n" return (n+1) $ ghc test.hs $ ./a.out $ diff foo bar 10d9 < 10:10 -- personal web site: http://www.acooke.org/andrew personal mail list: http://www.acooke.org/andrew/compute.html
On Thu, Nov 27, 2003 at 04:09:00PM -0300, andrew cooke wrote:
Hi,
If I compile and run the code below, the file "foo" contains 10 lines of output (as I would expect), but the file "bar" contains just 9 - the final line is missing. If I add a "join", as in the comment, then all 10 lines appear.
I don't understand why, completely - my best guess is that it's related laziness and the final result of the fold not being used.
No, it's not about laziness. The last result (action of type IO Int) is not threaded through the IO monad (forgive me the clumsy wording).
However, in that case, I'm worried that the "join fix" isn't guaranteed to work.
Join will work, but why are you using such a strange code anyway ? Best regards, Tom -- .signature: Too many levels of symbolic links
Tomasz Zielonka said:
On Thu, Nov 27, 2003 at 04:09:00PM -0300, andrew cooke wrote: [...]
If I compile and run the code below, the file "foo" contains 10 lines of output (as I would expect), but the file "bar" contains just 9 - the final line is missing. If I add a "join", as in the comment, then all 10 lines appear.
I don't understand why, completely - my best guess is that it's related laziness and the final result of the fold not being used.
No, it's not about laziness. The last result (action of type IO Int) is not threaded through the IO monad (forgive me the clumsy wording).
Ah. Thanks. I understand what you mean in general terms - I'll have to go back and look at the code to understand in detail. [...]
Join will work, but why are you using such a strange code anyway ?
It was a simplified version of more complex code that drives a progress meter - as the list is consumed IO is performed. It wasn't designed from the bottom up to support IO in such a low-level part of the code. The simplest solution was to have the list be of "IO a" rather than "a" (the IO coming from teh changing state of the progress meter). Then the fold over the list values gives code similar to what I posted. Hope that makes some sense. I'm still getting to grips with IO - it seems a lot less complicated than I first thought, but I still don't have much practice at structuring programs that use it. So it's possible it's a rather odd solution. Cheers, Andrew -- personal web site: http://www.acooke.org/andrew personal mail list: http://www.acooke.org/andrew/compute.html
participants (2)
-
andrew cooke -
Tomasz Zielonka