
Chad Scherrer wrote:
Here's an example of the problem. Start with a function
extract :: [Int] -> [a] -> [a] extract = f 0 where f !k nss@(n:ns) (x:xs) | n == k = x : f (k+1) ns xs | otherwise = f (k+1) nss xs f _ _ _ = []
If you want this to play nicely with stream fusion, you have to define a version of extract which works on streams instead of lists: extractS :: Stream Int -> Stream a -> Stream a Now, you can easily define a fusible list version: extract ns xs = unstream (extractS (stream ns) (stream xs)) In general, I don't see why programming directly with streams is something that should be avoided. You do have to be quite careful, though, if you want to get good performance (but GHC's simplifier is becoming increasingly robust in this respect).
extract ns xs == [xs !! n | n <- ns]
Note that in contrast to your function, this doesn't assume that ns is sorted and hence, there is no way to implement this without producing an intermediate list. Roman