Johan Tibell johan.tibell at gmail.com
Wed Jul 18 05:16:44 EDT 2007

```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 at 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
>
> _______________________________________________