Есть две строгие версии функции zipWith:
1) Действительно строго, элементы списков l1 и l2 оцениваются, поэтому их преобразователи не занимают все пространство стека (код Дона Стюарта)
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) ]
Вопрос: почему эквивалентный код из 2-го примера с использованием map не делает функцию еще и строгой?
zipWith'
заставит преобразовать любой элемент в l1 и l2 по мере обработки элементов, но преобразовательf e1 e2
не будет принудительно выполнен. - person augustss   schedule 28.06.2011