[Haskell-cafe] Re: evaluate vs seq
viritrilbia at gmail.com
Mon Sep 11 00:47:41 EDT 2006
On 9/10/06, apfelmus at quantentunnel.de <apfelmus at quantentunnel.de> wrote:
> > The GHC documentation says that (evaluate a) is not the same as (a
> > `seq` return a). Can someone explain the difference to me, or point
> > me to a place where it is explained?
> (evaluate a) is "weaker" than (a `seq` return a). (a `seq` return a) is
> always _|_ whereas (evaluate a) is not _|_, but does throw an exception
> when executed.
Okay... I think maybe I understand now. To check my understanding,
is the following a correct description?
* (return a) = produces an IO action which, when executed, returns a
in the IO monad, but lazily evaluated. Thus, if a is undefined, it
doesn't throw an exception unless and until its value is actually
* (a `seq` return a) = evaluate a *right now*, then produce an IO action
which, when executed, returns the result of evaluating a. Thus, if
a is undefined, throws an exception right now.
* (evaluate a) = produces an IO action which, when *executed*, evaluates
a (not lazily) and returns the result in the IO monad. Thus, if a is
undefined, throws an exception if and when the IO action in question
If this is correct, then the way I would explain your examples is
as follows. The "1" versions always throw an exception, since that
happens when the function is first called.
> e 0 = return a
> e 1 = a `seq` return a
> e 2 = evaluate a
> t x = e x >> return ()
> -- t 0 == return ()
> -- t 1 == throwIO something
> -- t 2 == throwIO something
Here the IO action is executed, so 2 throws an exception; but its
value is never used, so 0 doesn't.
> u x = e x `seq` return ()
> -- u 0 == return ()
> -- u 1 == undefined
> -- u 2 == return ()
Here the IO action is never even executed, since it gets replaced with
(return ()), so neither 0 nor 2 throws an exception.
> v x = catch (e x) (\_ -> return ()) >>= print
> -- v 0 == throwIO something
> -- v 1 == print ()
> -- v 2 == print ()
Here, again, the IO action is executed, so 2 throws an exception at
that point, which gets caught and so the result is replaced with ().
But 0 executes with no problem and returns a, lazily evaluated, which
thereby slips out from under the `catch' to throw an error when its
value is actually used, later, by `print'.
Is that all correct?
Thanks for your help!
More information about the Haskell-Cafe