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

Magnus Therning magnus at therning.org
Wed Oct 21 11:49:23 EDT 2009


On Wed, Oct 21, 2009 at 9:44 AM, Michael Mossey <mpm at alumni.caltech.edu> wrote:
>
>
> 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.

Laziness in combination with IO is a difficult thing.  Just search the
archives to see the number of threads about 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.

Just out of curiosity, did you verify that all three files were
completely *read*, as opposed to all three opened, but only the first
line of the first file being read?

/M

-- 
Magnus Therning                        (OpenPGP: 0xAB4DFBA4)
magnus@therning.org          Jabber: magnus@therning.org
http://therning.org/magnus         identi.ca|twitter: magthe


More information about the Beginners mailing list