为什么map不强制严格,而zipWith呢?

Dav*_*ric 5 haskell lazy-evaluation strictness

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)
Run Code Online (Sandbox Code Playgroud)

2)不是很严格,试图通过其他方式强制评估.

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

问题是:为什么使用map的第二个例子的等效代码不会使函数也严格?

jas*_*vdj 15

这是一个常见的错误

x `seq` x
Run Code Online (Sandbox Code Playgroud)

这完全等同于

x
Run Code Online (Sandbox Code Playgroud)

Neil Mitchell关于Bad Strictness的文章中提供了一个很好的解释.