有两个严格的zipWith函数版本:
1)非常严格,列表l1和l2的元素得到评估,因此他们的thunk不会占用所有堆栈空间(Don Stewart代码)
zipWith' f l1 l2 = [ f e1 e2 | (e1, e2) <- zipWith k l1 l2 ]
where
k x y = x `seq` y `seq` (x,y)
2)不是很严格,试图通过其他方式强制进行评估。
zipWith'' f l1 l2 = [ f e1 e2 | (e1, e2) <- zip (map (\x -> x `seq` x) l1) (map (\x -> x `seq` x) l2) ]
问题是:为什么使用 map 的第二个例子中的等效代码不会使函数也严格?
答案 0 :(得分:15)
答案 1 :(得分:3)
可以使用此函数强制列表,而不是重言map
:
evl [] = []
evl (x:xs) = x `seq` (x:evl xs)
-- Cannot figure out how to do this with fold.
然后严格的zipWith
是
zipWith''' f xs ys = zipWith f (evl xs) (evl ys)