I don't understand why my implementation of this function for a tutorial exercise fails to be lazy. It fails when running take 4 (chunks 3 [0..]). Please advise me what to change.
I'm not doing anything that I think would cause an infinite list to be evaluated:
- no length function
- no pattern matching on the list that requires computation
- no tail function
- no right side calculations
-- chunks 2 [1,2,3,4] ==> [[1,2],[2,3],[3,4]]
-- take 4 (chunks 3 [0..]) ==> [[0,1,2],[1,2,3],[2,3,4],[3,4,5]]
chunks :: Int -> [a] -> [[a]]
chunks len input = chunks' len input []
chunks' :: Int -> [a] -> [[a]] -> [[a]]
chunks' _ [] output = output
chunks' len input@(input1:inputTail) output
| lengthAtLeast len input = chunks' len inputTail (output++[take len input])
| otherwise = output
where
lengthAtLeast len list = length (take len list) >= len