I have two functions similar to filter and takeWhile.
filterAcc, takeWhileAcc :: ([a] -> Bool) -> [a] -> [a]
filterAcc p xs = go xs []
where go [] acc = acc
go (x:xs) acc
| p (x:acc) = go xs (x:acc)
| otherwise = go xs acc
takeWhileAcc p xs = go xs []
where go [] acc = acc
go (x:xs) acc
| p (x:acc) = go xs (x:acc)
| otherwise = acc
they both take predicates and lists, and they differ from the regular filter and takeWhile in that the predicates take the accumulated result as inputs.
my problem is that while filter even [1..] will start producing output immediately (lazily), filterAcc (any even) [1..] hangs. My suspicion is that the helper function go is preventing these functions from acting lazily.
How can i make these functions operate lazily?
The problem is that the cons case of
goalways ends in a tail call to itself. It only returns something useful when it’s reached the end of the list, which of course never happens with an infinite list.Instead, you should return elements as you go: