Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a function to every second element in a list

Tags:

list

haskell

I'd like to apply a function to every second element in a list:

> mapToEverySecond (*2) [1..10]
[1,4,3,8,5,12,7,16,9,20] 

I've written the following function:

mapToEverySecond :: (a -> a) -> [a] -> [a]
mapToEverySecond f l = map (\(i,x) -> if odd i then f x else x) $ zip [0..] l

This works, but I wonder if there is a more idiomatic way to do things like that.

like image 655
Nausika Avatar asked Jan 31 '15 21:01

Nausika


1 Answers

I haven't written very much Haskell, but here's the first thing that came into mind:

func :: (a -> a) -> [a] -> [a]
func f [] = []
func f [x] = [x]
func f (x:s:xs) = x:(f s):(func f xs)

It is a little ulgy, since you have to not only take care of the empty list, but also the list with one element. This doesn't really scale well either (what if you want every third, or

One could do as @Landei points out, and write

func :: (a -> a) -> [a] -> [a]
func f (x:s:xs) = x:(f s):(func f xs)
func f xs = xs

In order to get rid of the ugly checks for both [] and [x], though, IMHO, this makes it a little harder to read (at least the first time).

like image 194
MartinHaTh Avatar answered Oct 21 '22 03:10

MartinHaTh