[Haskell-cafe] How to construct a lazy list of eagerly-evaluated items?

Daniel Fischer daniel.is.fischer at web.de
Sat May 22 20:38:48 EDT 2010


On Sunday 23 May 2010 01:10:54, Vladimir Ch. wrote:
> I'm using Project Euler to learn Haskell. In particular, I'm writing a
> program for Problem 18:
<snip>
>
> The program works, but consumes obscene amount of memory.

Not if it's compiled. Even interpreted I wouldn't call it obscene, though 
it is rather bad.

> I suspect that
> it's because of lazy evaluation of items in the list we're constructing
> (and also using during construction).

Not really. Your problem is that you calculate maxPaths vals over and over 
again in
   where mpath i val = val + maximum [(maxPaths vals) !! pi| pi <- prev i]
; the value isn't shared (it is, if compiled with optimisations).
If you share the list by giving it a name, your programme becomes much 
faster (interpreted or compiled without optimisations; with -O, it's below 
measuring accuracy anyway) and needs only a little memory:

maxPaths vals@(v:vs) = mps
  where
    mps = v : zipWith mpath [1 .. ] vs
    mpath i val = val + maximum [mps !! pi| pi <- prev i]

> How can I force eager evaluation
> of items, put into the list?

That's a little tricky. Fortunately, it's not necessary.

>
> Any other comments and suggestions are also very welcome.

You can get rid of the index calculations and the list indexing if you work 
on the list of rows (i.e., make triangle18 :: [[Int]]).
IMO, the code will be easier to follow then, too.

>
> I know index-based item lookup in a list is not efficient, but I'll take
> care of this later (I don't know much about arrays yet). For now, I'm
> more concerned with the memory usage.



More information about the Haskell-Cafe mailing list