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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With