[Haskell-beginners] SOLVED - Stack overflow, but hard to understand

Michael Mossey mpm at alumni.caltech.edu
Wed Oct 21 04:44:38 EDT 2009



Magnus Therning wrote:
> On 20/10/09 20:32, Michael Mossey wrote:
>> Okay, I figured this out. mapM is not lazy, at least not for a monad that
>> has state and under the circumstance you demand the state out the other
>> side.
> 
> If I understand what you are saying then this behaviour isn't 
> unexpected.  If
> you have a monad with state, and you ask for the final state, then it's 
> likely
> that everything happening in that particular monad will has to be 
> evaluated.

Hi Magnus,

Yes, that's what I was trying to imply. I realized it is mathematically 
impossible for mapM to be lazy for a monad with state.

mapM doesn't seem to be lazy anywhere. For example, this program

main = do
    buffers <- forM ["file1.txt","file2.txt","file3.txt"] readFile
    print . take 1 . concat $ buffers

will, according to my experiments with the profiler, read all three files. 
It's possible to imagine lazy behavior here, but no doubt there is a 
technical reason against it.

> 
>> I may rewrite the program. Or I may consider the ISS principle.
>> ("Increase the stack, stupid.")
> 
> You may also be able to improve the situation by adding a bit of 
> strictness.
> In some cases the thunks resulting from laziness can take up a lot of 
> space.
> Forcing evaluation, at well thought out locations in your program, may both
> speed things up and reduce memory/stack usage.

You are probably right... I am having trouble spanning the gap between "my 
current understanding" and "well thought-out locations." Real World Haskell 
has a chapter on this, so I may look there.

I was able to get the program to run by removing all places that I had 
created a chain of Rand computations that forced evaluation of the last 
one. I replaced these with computations that did not require evaluation of 
the last one.

However, my program was still forced to read more files than it really 
needed in the end, as the above snippet demonstrates.

Thanks,
Mike


More information about the Beginners mailing list