zipWith 関数には 2 つの厳密なバージョンがあります。
1) 非常に厳密で、リスト l1 と l2 の要素が評価されるため、それらのサンクがすべてのスタック スペースを消費することはありません (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を使用した 2 番目の例の同等のコードで、関数も厳密にならないのはなぜですか?