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 <apfelmus@quantentunnel.de> wrote:
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