I'd say its easier to implement takeWhile using foldr:
takeWhile p = foldr (\x xs -> if p x then x : xs else ) 
Also, foldr most definitely does not consume the whole list before producing a result. Take this definition:
foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z  = z foldr f z (x:xs) = f x (foldr f z xs)
As you can see in the cons case; foldr calls
and the result of a recursive call.
However, since Haskell is lazy,
gets executed before
the result of the recursive call is computed. If
decides to never inspects its second argument, the recursive call will never be evaluated. So that's why you can do:
takeWhile (<4) [0..]
However, you are right about foldl.
foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z  = z foldl f z (x:xs) = foldl (f z x) xs
first recurses, before executing the
function that produces the result value.
So calling the
takeWhile', defined below, with an infinite list will result in an infinite computation.
takeWhile' p = foldl (\ys x -> if p x then ys ++ [x] else ys)