[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