
`takeWhile` doesn't do the stream fusion thing. This definition seems to fix that, at least to a great extent. I don't know how to write the necessary rules to make this definition be used in the right places. takeWhile :: forall a . (a -> Bool) -> [a] -> [a] takeWhile p xs = build tw' where tw' :: forall b . (a -> b -> b) -> b -> b tw' kons knil = foldr go knil xs where go x rest | p x = x `kons` rest | otherwise = knil Tests (performed on 7.8.3, but the definition hasn't changed in HEAD): In the trivial main = print $ length $ takeWhile (< 10000000) [(1::Int) .. 20000000] it fused completely, allocating virtually nothing, whereas using Prelude.takeWhile (on 7.8.3) required a whopping 1,360,049,352 In the more complex main = print $ length $ filter (\x -> x `rem` 3 == 0) $ takeWhile (< 10000000) $ filter even [(1::Int) .. 20000000] it fused partially, allocating 266,716,048 bytes. The current GHC definition allocates 746,716,000 bytes in this case (strangely, less than it used for the simple test)! David Feuer