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?
zipWith'
function will force any element thunks in l1 and l2 as it processes the elements, but thef e1 e2
thunk is not forced. – Judie