[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