Double every 2nd item in a list Some exercise required me to write a piece of code to double every second item in a list. My first thought was just using cons and I came up with the following:

doubleSecond :: Num a =&gt; [a] -&gt; [a]
doubleSecond [] = []
doubleSecond [x] = [x]
doubleSecond (x:y:xs) = x : (y * 2) : doubleSecond xs


While it's straightforward and does work, it just doesn't look that elegant and I'm curious how this could be rewritten in a more elegant fashion :)
Built-ins and generality

It is a good first try, but I discourage explicit recursion and suggest a larger use of built-ins, Haskell provides you with incredibly powerful and general functions. Also writing something a bit more general will make you familiar with first class functions (the core of the Haskell experience).

Decomposition

As always, I am going to divide the task in smaller, more manageable parts:


Find out how to apply a function to each second item of list.
Give multiply_by_two as argument to the function above.


mapSecond

mapSecond :: (a -&gt; a) -&gt; [a] -&gt; [a]
mapSecond f = zipWith ($) (cycle [id, f])


Given a function and a list, apply the function to each second item of the list.

This function is quite advanced, let me explain it:


zipWith: given a function and two list applies the function to each pair. If you are familiar with Python, zip = zipWith (,)




Prelude&gt; zipWith (++) ["Hello", "Foo"] ["World", "Bar"]
["HelloWorld","FooBar"]



$: given a function and two arguments, applies it to the arguments. 




Prelude&gt; ($) (*) 2 5
10



cycle: given a list repeats it forever.




Prelude&gt; take 10 $ cycle [1,2,3]
[1,2,3,1,2,3,1,2,3,1]


The second argument is omitted, as it can be 'currried' (simplified) away.

The main function is now:

main = print $ ( mapSecond (* 2) ) [1,2,3,4,5,6]