producing and consuming lists

Jorge Adriano
Tue, 5 Nov 2002 16:04:58 +0000

I might have been not very clear in my last mail. I decided to post again=
, and=20
go straight to the point, with some small examples.

Consider the following function streams.

streams :: (Int->Bool, Int->Bool)->(Int, Int)->([Int],[Int])
streams (p,q) (x,y) =3D (xs',ys')
    (xs,ys) =3D streams (p,q) ((x+y),(y-x))
    xs' =3D if p x then x:xs else xs
    ys' =3D if q y then y:xs else ys

- produces a pair of ('infinite') lists
- produced lists are not indepentent (you need to calculate elements of o=
list to calculate elements of the other)
- in each recursive call an element is added to the 1st/2nd list iff  it=20
satisfies a given (Int->Bool) function p/q

How should one consume (part of) both lists, avoiding space leaks?

A particular example of consuming both lists might be writing them to fil=
main :: IO()
main =3D do
       let (s1,s2)=3Dstream ... -- stream applied to some arguments (p,q)=
           p' =3D ...=20
           q' =3D ...=20
       writeFile "f1.txt" (show$ takeWhile p' s1)
       writeFile "f2.txt" (show$ takeWhile q' s2)

In this example all elements of s2 required to evaluate (takeWhile p' s1)=
kept in memory, until the first file is writen. Notice that writing one=20
element from s1 and one from s2 successively might still cause space leak=
s to=20
arise. Fusing the consuming functions with the producer is a possible, bu=
IMO dirty, way out.=20

If my question doesn't seem to make sense for any reason, please tell me,=
maybe I am missing something obvious here.=20