<[EMAIL PROTECTED]> asks:
> Is the following the expected behavior?  Heap size is 1000000.
> 
> Prelude> foldl (+) 0 (replicate 6000 1)
>  
> ERROR: Control stack overflow

That sounds pretty plausible.

Take a smaller example:

  foldl (+) 0 [1..5]

A Haskell compiler will evaluate this as follows:

  foldl (+) 0 [1..5]
 =
  foldl (+) (0+1) [2..5]
 =
  foldl (+) (0+1+2) [3..5]
 =
  ...
 =
  foldl (+) (0+1+2+3+4+5) []
 = 
  0+1+2+3+4+5
 =
  15

Notice that no additions happen until the very end.  If you look
at a graph of stack usage during this evaluation, you'll probably
see a dead-flat section while it's in foldl and then stack usage
will go through the roof at the end.

The problem here is laziness - we'd like the compiler to evaluate the
accumulating argument as it goes along but Hugs doesn't know this.
(Other Haskell compilers might spot this if you turned "strictness
analysis" on??)

The fix is to use "strict" and "seq" to make your intentions clear.
Here's how the Hugs Prelude implements sum and product:

sum, product     :: Num a => [a] -> a
sum               = foldl' (+) 0
product           = foldl' (*) 1

foldl'           :: Eval a => (a -> b -> a) -> a -> [b] -> a
foldl' f a []     = a
foldl' f a (x:xs) = strict (foldl' f) (f a x) xs

The call to "strict" in the above makes Hugs evaluate "f a x"
before the recursive call to foldl' instead of saving the evaluation
up until the end.

Alastair


Reply via email to