[Haskell-cafe] Control.Exception.evaluate - 'correct definition' not so correct

Bryan Donlan bd at fushizen.net
Sat May 3 05:19:17 EDT 2008


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20080503/c8447352/attachment.bin


More information about the Haskell-Cafe mailing list