
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