
It would be nice if it was possible to capture this kind of behavior in a
high order function just like map though. I guess the problem is that the
function to map will take different number of arguments depending on the use
case.
lookAtTwo a b = ...
lookAtThree a b c = ...
map' :: (a -> ... -> b) -> [a] -> [b]
The parameter take a variable number of parameters.
Note: I don't know if there is a sensible way to write map' at all. Perhaps
explicit recursion is better in this case.
On 7/18/07, apfelmus
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.
There are some cases missing, like
f [x] = ?? f (Bar a : Foo b : xs) = ??
A better example is probably
takeUntilConvergence epsilon (x:x':xs) | abs (x-x') < epsilon = [x] | otherwise = x:takeUntilConvergence epsilon (x':xs)
useful for numeric iterations like
sqrt a = last $ takeUntilConvergence (1e-10) $ iterate (\x -> (x+a/x)/2) 1
Another way to implement takeUntilConvergence is to zip the list with its tail:
takeUntilConvergence epsilon xs = fst . head . dropUntil ((< epsilon) . snd) $ zipWith (\x x' -> (x,abs(x-x')) xs (tail xs)
Regards, apfelmus
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe