On 13-03-08 11:53 PM, Edward Z. Yang wrote:
Are these equivalent? If not, under what circumstances are they not
equivalent? When should you use each?
evaluate a >> return b
a `seq` return b
return (a `seq` b)
Let a = div 0 0
(or whatever pure but problematic expression you like)
b can be the same as a or something else.
First assume IO. The 3rd one is distinguished by
main = m >> return ()
where m is to be plugged in the 1st, 2nd, or 3rd. During IO execution,
the 1st and 2nd throw an exception, the 3rd one does not.
The 2nd is distinguished by
main = evaluate m
During IO execution, the 2nd throws an exception, the 1st and 3rd do
not. (m `seq` return () should also do the same.)
In practice, we seldom artificially evaluate or seq an IO action like
that. And so, that distinction between the 1st and 2nd is seldom
observed. But another difference matters more in practice:
main = head [] `seq` (a `seq` return b)
Two consecutive seqs is an instance where the impreciseness of imprecise
exceptions kicks in. The compiler reserves the right to prefer either
the empty-list exception or the divide-by-0 exception; perhaps even a
difference choice at a different time. Whereas:
main = evaluate (head []) >> (evaluate a >> return b)
By virtue of IO's serializing >> (and lack of unsafeInterleaveIO hehe),
the exception thrown must be the empty-list one.
If the monad is not IO, then we cannot discuss evaluate. But we can be
sure that different monads behave differently, and the difference
involves >>=. Example:
import Control.Monad.State.Strict
a = div 0 0
b = whatever you like
main = print (evalState ((a `seq` return b) >> return ()) ())
-- throws an exception
import Control.Monad.State.Lazy
a = div 0 0
b = whatever you like
main = print (evalState ((a `seq` return b) >> return ()) ())
-- does not throw an exception
(Did you know: Control.Monad.State refers to the Lazy one.)
I leave the rest of the questions unanswered. Enough mind-bending for
today! :)
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe