2
votes

I am trying to write a Haskell function that takes two unary functions (f and g) and a list of numbers (ns) and alternatively applies those input functions f and g to the elements of the inputted list.

For example:

func double square [2, 3, 4, 5, 6]

would return

[4, 9, 8, 25, 12]

I am using WinGHCi for my compiler. Any help on writing this function would be appreciated, thanks.

3
Check out zipWith and cycle.luqui
I'm trying not to use library functions, and I don't see how zipWith would help...T-Bird
Why not use library functions?Rodrigo Ribeiro
@T-Bird: Avoiding library functions is not a good idea. Good functional programming style involves splitting problems into smaller pieces and solving these with generic, reusable functions as the ones found in the standard libraries. So the best strategy is to (a) use standard library functions to solve your problem, and then (b) write your own versions of the functions as an additional exercise. And this is a recursive solution, since you may use other library functions in step (b)...Luis Casillas

3 Answers

6
votes

If you don't want to use any library functions, you can do this by using recursion:

func _ _ []     = []
func f g (x:xs) = f x : func g f xs
2
votes

Expanding on @luqui's comment:

func f1 f2 l = zipWith ($) (cycle [f1, f2]) l

If you don't want to use library functions, just look up their implementations, they're quite simple.

-2
votes

Just a simple solution...

fun :: (a -> b) -> (a -> b) -> [a] -> [b]
fun f g = reverse . snd . foldl step (0,[])
          where
             step (c,ac) x = (c + 1, (if even c then f x else g x) : ac)

Since you do not want to use library functions, you can reproduce the same result without using foldl. The idea is simple to use a counter to know which position is even or not.

Edit: I've made a little confusion on my accumulator. Now, it is correct.