Почему map не устанавливает строгость, тогда как zipWith делает?

Есть две строгие версии функции 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 также не выполняет функцию strict?

5
задан hammar 30 September 2011 в 19:18
поделиться