On 15 April 2004 05:20, Stefan Ljungstrand wrote:

> The code is a small modification of mine to the attribute-grammar-like
> (multi-pass lazy) example with recursive IO at
> http://www.cse.ogi.edu/PacSoft/projects/rmb/repMin.html
> 
> The original code replaces every (leaf) elements in a tree by the
> minimum 
> of them all, returning the new tree, while printing out the elements,
> in traversion order.
> 
> My modification tries to also print out minimum (at each non-leaf
> call) 
> the global minimum (which is lazily passed down as a value from the
> 'future'). Probably this should generate a "Fail: <<loop>>" at first
> attempt to prematurely force the global minimum (or maybe earlier).
> 
> The problem is, it actually duplicates some of the other IO effects a
> few times, before grinding to a "Fail: <<loop>>" stop !

What is happening here is that your program goes into an infinite loop
(as expected), but GHC doesn't notice the loop for a while.  This is
because GHC does something called "lazy blackholing".  When it does
finally notice the loop, you get a NonTermination exception.

Probably the correct thing to do here is for GHC to guarantee to give
the black hole exception immediately.  I believe this is what the fixIO
semantics proposed by Erkok et. al. specifies (Levent or John - can you
comment?).

We can define fixIO like this, which does what you want:

fixIO :: (a -> IO a) -> IO a
fixIO k = do
    ref <- newIORef (throw NonTermination)
    ans <- unsafeInterleaveIO (readIORef ref)
    result <- k ans
    writeIORef ref result
    return result

Cheers,
        Simon
_______________________________________________
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to