Processing a list 1..n elements at a time without explicit recursion
I find myself often using a pattern where I transform a list with a function that consumes 1..n elements from the list and produces some result out of those. E.g.
process :: [a] -> [b]
process [] = []
process xs = first : rest
where (first, xs') = consume xs
rest = process xs'
Where the consume
function consumes a variable number of items from the list and returns a result and the remaining开发者_Python百科 list items. Can I use some standard higher order function here instead of the explicit recursion?
The function you need is similar to unfoldr
. If you would bring your consume
into the following form:
consume' :: [a] -> Maybe (b,[a])
Where consume'
returns Nothing
in case of an empty list, or Just ...
otherwise. This is a small wrapper, that captures that pattern:
wrap :: ([a] -> (b,[a])) -> [a] -> Maybe (b,[a])
wrap f [] = Nothing
wrap f xs = Just $ f xs
Then you can use consume
with unfoldr
with the original definition of consume :: [a] -> (b,[a])
like this:
unfoldr (wrap consume)
You can use unfoldr
with some wrapper around consume
, but I wish there where a higher order function for exactly the pattern you have. I have suggested adding one to Data.List
. I too use it a lot.
精彩评论