2

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.

T-Bird
  • 187
  • 1
  • 4
  • 20
  • 4
    Check out `zipWith` and `cycle`. – luqui Dec 09 '15 at 00:06
  • See http://stackoverflow.com/questions/17383169/haskell-double-every-2nd-element-in-list/17383354#17383354 – Thomas M. DuBuisson Dec 09 '15 at 00:10
  • 1
    I'm trying not to use library functions, and I don't see how zipWith would help... – T-Bird Dec 09 '15 at 00:10
  • Why not use library functions? – Rodrigo Ribeiro Dec 09 '15 at 00:24
  • @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 Dec 09 '15 at 01:24

3 Answers3

6

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
Michael Szvetits
  • 364
  • 1
  • 2
  • 11
2

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.

fjarri
  • 9,546
  • 39
  • 49
-2

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.

Rodrigo Ribeiro
  • 3,198
  • 1
  • 18
  • 26