
Sounds like what I want. I'll give it a try. Thanks.
On 7/18/07, Tillmann Rendel
Johan Tibell wrote:
I found myself wanting a map that looks at neighboring elements. This is where I used explicit recursion the most. Something like this:
f [] = [] f ((Foo a) : (Bar b) : xs) | fooBar a b = Foo a : f xs | otherwise = Bar b : f xs
This is almost a map. A variation is when filtering and you want some look-ahead to make the filtering decision. There's probably a good way to do this I'm not aware of.
If you want to map over all elements, but need to look ahead in the mapped function, you can map over the tails:
map' :: ([a] -> b) -> [a] -> b map' f = map f . tails
f should be something like f (a:b:c:_) = ...
If you want to handle groups of n elements together, producing only one element per group, you can use unfoldr with splitAt:
map'' :: Int -> ([a] -> b) -> [a] -> [b] map'' n f = map f . unfoldr (((not . null . fst) `guarding`) . splitAt n)
guarding p x = guard (p x) >> return x
If you want to decide in the mapped function how many elements to consume, you can use unfoldr directly.
Tillmann Rendel