Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why map does not force strictness whereas zipWith does?

There are two strict versions of zipWith function:

1) Really strict, elements of lists l1 and l2 get evaluated so their thunks do not eat all stack space (Don Stewart code)

zipWith' f l1 l2 = [ f e1 e2 | (e1, e2) <- zipWith k l1 l2 ]
            where
                k x y = x `seq` y `seq` (x,y)

2) Not really strict, attempt to force evaluation by other way.

zipWith'' f l1 l2 = [ f e1 e2 | (e1, e2) <- zip (map (\x -> x `seq` x) l1) (map (\x -> x `seq` x) l2) ]

The question is: why the equivalent code from the 2nd example using map does not make the function also strict?

like image 351
David Unric Avatar asked Jun 28 '11 08:06

David Unric


1 Answers

It's a common mistake to use

x `seq` x

Which is exactly equivalent to

x

An excellent explanation is available in Neil Mitchell's post on Bad Strictness.

like image 55
jaspervdj Avatar answered Oct 10 '22 05:10

jaspervdj