[Haskell-cafe] To seq or not to seq, that is the question
Albert Y. C. Lai
trebla at vex.net
Sun Mar 10 21:56:00 CET 2013
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! :)
More information about the Haskell-Cafe
mailing list