A "map" function that alternates between two mapping functions I am trying to solve following problem in Haskell using recursion:


  Define a recursive function funkyMap :: (a -&gt; b) -&gt; (a -&gt; b) -&gt; [a] -&gt; [b] that takes as arguments two functions f and g and a list xs, and applies f to all elements at even positions [0, 2..] in xs and g to all elements at odd positions [1, 3..] in xs.


Example: funkyMap (+10) (+100) [1, 2, 3, 4, 5] = [(+10) 1, (+100) 2, (+10) 3, (+100) 4, (+10) 5].

I came up with following solution:

h1 p q [] = []
h1 p q ((cnt, val) : xs) = (if odd cnt then (q val) else (p val) ) : h1 p q xs

funkyMap f g xs = h1 f g ( zip [0..] xs)


If I try funkyMap (+10) (+100) [1, 2, 3, 4, 5] I get [11,102,13,104,15] which is expected.

Also funkyMap (+100) (+2) [1] gives [101]

and funkyMap (+100) (+2) [] gives []

Please review this solution and let me know your feedback.
So, like @pigworker has said your code looks functionally good to me, but you don't have to break up your solution into two parts like this or create a data structure you don't need.

You might find a better solution using a different approach (pattern matching):

funkyMap :: (a -&gt; b) -&gt; (a -&gt; b) -&gt; [a] -&gt; [b]
funkyMap p q [] = []
funkyMap p q [x] = [p x]
funkyMap p q (x : y : xs) = p x : q y : funkyMap p q xs


The real benefit of this is you don't have to create any intermediate data structures. 

The idea behind this solution is to let pattern matching do the hard work for you. Really you have 3 senarios for your function


when there are no elements in the list (where you probably just want to return the empty list)
when you have just one element in the list (where you just want to apply p to the element)
when you have 2 or more elements in the list (where you apply p and q, then use recursion to evaluate the rest of the list)


Using pattern matching lets you wrap that logic up in a really obvious way