Strict evaluation not working?

Hi, having found a bit of time to play with Haskell, I am trying to figure out how to enforce strict evaluation. I wrote the following program: main = let x = zipWith (+) [5..] [6..] in putStrLn $ show $ x `seq` head x I expected this program not to terminate - because of the seq-Operator, but it happily returns 11 in ghc as well as in ghci. What do I make wrong? Chris

On 2004-10-12 at 18:07+0200 Christian Hofer wrote:
Hi,
having found a bit of time to play with Haskell, I am trying to figure out how to enforce strict evaluation. I wrote the following program:
main = let x = zipWith (+) [5..] [6..] in putStrLn $ show $ x `seq` head x
I expected this program not to terminate - because of the seq-Operator, but it happily returns 11 in ghc as well as in ghci. What do I make wrong?
head is strict in its first argument, so x `seq` head x is equivalent to head x. seq only evaluates to (w?)hnf. To do more you would need deepSeq. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

main = let x = zipWith (+) [5..] [6..] in putStrLn $ show $ x `seq` head x
I expected this program not to terminate - because of the seq-Operator, but it happily returns 11 in ghc as well as in ghci. What do I make wrong?
"seq" forces its argument to "Weak Head Normal Form". In plain English, that means that it insists that the topmost constructor is specified (here whether x is [] or (:)), but nothing more. If you want to force the entire data structure, you have to walk over it, forcing every part of it. Often people use a DeepSeq class to achieve this. But if you are just learning Haskell, you almost certainly don't need to do this. Just make use of the laziness, and learn to love it! Come back to "seq" when you are writing a large application, and profiling tells you you have a space leak. --KW 8-)

Am 12.10.2004 um 18:20 schrieb Keith Wansbrough:
But if you are just learning Haskell, you almost certainly don't need to do this. Just make use of the laziness, and learn to love it!
Thank you for your replies. You are right: I don't need it. It's just that I am currently studying the book Algorithms by Rabhi/Lapalme, and in their section about tail recursivity optimization they write: "Note that in a lazy language, this optimization only works if the parameters of the recursive call are strictly evaluated. If not, the space occupied by the old function call cannot be reused since it contains references to unevaluated arguments." (p. 67) For me, "seq" does not seem to solve the problem, then: I can still have a partly unevaluated argument that is bound to the environment of the calling function. Is this correct? Chris
participants (3)
-
Christian Hofer
-
Jon Fairbairn
-
Keith Wansbrough