
streams :: (Int -> Bool, Int -> Bool) -> (Int,Int) -> [(Maybe Int,Maybe Int)] streams (p,q) (x,y)
| p x && p y = (Just x , Just y ) : xs | p x = (Just x , Nothing) : xs | p y = (Nothing, Just y ) : xs | otherwise = xs
where xs = streams (p,q) ((x+y),(y-x))
With this setup, I think you can write your own writefile function which looks something like: I think, but I'm not sure, that this will allow the old stuff to be garbage collected. In practice, you don't get too much useless junk generated because we don't append the (Nothing,Nothing) pair to the list Nice observation, I missed that one since I didn't paired both lists :) But like I just showed, sometimes paring them may not be a natural approach
Yeap, in fact I thought about it when answering Toms answer. Doesn't seem good enough in more general cases though, Like: streams :: (Int->Bool, Int->Bool)->(Int, Int)->([Int],[Int]) streams (p,q) (x,y) = (xs',ys') where (xs,ys) = streams (p,q) ((x+y),(y-x)) xs' = if p x then x:xs else zs++xs <------- ys' = if q y then y:xs else ys zs = some_other_stream <---------- Or: streams :: (Int->Bool, Int->Bool)->(Int, Int)->([Int],[Int]) streams (p,q) (x,y) = (xs',ys') where (xs,ys) = streams (p,q) ((x+y),(y-x)) xs' = if p x then x:xs else zs -- <------------ ys' = if q y then y:xs else ws -- <----------- zs = ... some other_stream -- <--- ws= ... yet_another_stream -- <--- though...
(erm, "prepend"). But what's more important, I think you only evaluate the same amount of each at any given time, thus allowing GC to gobble up the old stuff. Exactly
An expert might be able to prove me wrong, though, or you could try this and profile it and see if it works or not :) I haven't tested it yet either but seems to me like it should work, in this particular example.
I was hoping I could somehow take advantage of the fact that the order in which I want to consume the lists doesn't matter. I thought about concurrency but it doesn't seem to work. J.A.