Hi all,

After some discussion on #haskell I decided to bring this issue to
haskell-cafe. GHC's documentation for Control.Exception.evaluate states:

        evaluate :: a -> IO a

        Forces its argument to be evaluated when the resultant IO action is
        executed. It can be used to order evaluation with respect to other IO
        operations; its semantics are given by

           evaluate x `seq` y    ==>  y
           evaluate x `catch` f  ==>  (return $! x) `catch` f
           evaluate x >>= f      ==>  (return $! x) >>= f

        Note: the first equation implies that (evaluate x) is not the same as
        (return $! x). A correct definition is

           evaluate x = (return $! x) >>= return

However, if >>= is strict on its first argument, then this definition is
no better than (return $! x). One might next consider:

        evaluate x = (return x) >>= (return $!)

However, according to the monad laws, this is equivalent to:

        evaluate x = return $! x

and we're back to where we started. Although GHC's implementation of IO
is somewhat more relaxed about this, there is no guarentee that this
will be the case in all IO implementations, or future versions of GHC,
or different optimization flags, or...

The best I've come up with so far is:

        evaluate x = newIORef (return $! x) >>= join . readIORef

In any case, if >>= is to be guarenteed lazy, this ought to be
documented somewhere (or is it?). Otherwise Control.Exception's docs
should be updated to provide a more correct example and/or the caveat
that >>= must not be left-strict for the example implementation to be
correct.

Thanks,

Bryan Donlan

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to