Yang hehx0sk02 at sneakemail.com
Mon Oct 9 02:31:45 EDT 2006

```On 10/8/06, Udo Stenzel u.stenzel-at-web.de |haskell-cafe|
<...> wrote:
> Yang wrote:
> > type Poly = [(Int,Int)]
> >
> > addPoly1 :: Poly -> Poly -> Poly
> >    | p1d == p2d = (p1c + p2c, p1d) : addPoly1 p1t p2t
> >    | p1d < p2d = p1h : addPoly1 p1t p2
> >    | p1d > p2d = p2h : addPoly1 p1 p2t
> > addPoly1 p1 [] = p1
> > addPoly1 [] p2 = p2
> > addPoly1 [] [] = []
> >
> > But this doesn't use tail recursion/accumulation
>
> Indeed it doesn't.  Now remind me, why is that supposed to be a Bad
> Thing?  The above code exhibits a maximum of lazyness and runs with no
> useless space overhead.  Apart from the expression (p1c + p2c), which
> you probably want to evaluate eagerly, it is close to perfect.
>
> > so I rewrote it: [...]
> >
> > But laziness will cause this to occupy Theta(n)-space of cons-ing
> > thunks.
>
> No, it doesn't.  Insisting on accumulator recursion does.  Actually,
> using reverse does.  Think about it, a strict reverse cannot use less
> than O(n) space, either.

Well, in general, the problem you run into is this, where we use
linear space for the thunks:

foldl (+) 0 [1,2,3]
= foldl (+) (0 + 1) [2,3]
= foldl (+) ((0 + 1) + 2) 
= foldl (+) (((0 + 1) + 2) + 3) []
= ((0 + 1) + 2) + 3
= (1 + 2) + 3
= 3 + 3
= 6

whereas with strictness, you use constant space:

foldl' f z [] = z
foldl' f z (x:xs) = let u = f z x in u `seq` foldl' f u xs
foldl' (+) 0 [1,2,3]
= let u = 0 + 1 in u `seq` foldl' (+) u [2,3]
= foldl' (+) 1 [2,3]
= let u = 1 + 2 in u `seq` foldl' (+) u 
= foldl' (+) 3 
= let u = 3 + 3 in u `seq` foldl' (+) u []
= foldl' (+) 6 []
= 6

>
> > I was
> > hoping for more in-depth insights on how to take advantage of laziness
> > to write cleaner AND more efficient code.
>
> Try to explain why your first iteration was bad.  You'll achieve
> enlightenment at the point where your explanation fails.
>
>
> Udo.
> --
> Hast du zum Leben kein Motiv --
> steig mal vor, vielleicht geht's schief.
>         -- aus einem Gipfelbuch
>
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.1 (GNU/Linux)
>
> iD8DBQFFKYwQc1ZCC9bsOpURAs4KAKCymnLiE5LfkCa01H0AJ2FddwJ6oQCfY6DY
> sYRPT1fGr0mUozUcs+qGC8s=
> =BRLQ
> -----END PGP SIGNATURE-----
>
>
>
```