I just wanted to multiply two lists element by element, so I'd pass (*) as the first argument to that function:

```
apply :: Num a => (a -> a -> a) -> [a] -> [a] -> [a]
apply f xs ys = [f (xs !! i) (ys !! i) | i <- [0..(length xs - 1)]]
```

I may be asking a silly question, but I actually googled a lot for it and just couldn't find. Thank you, guys!

# Best How To :

```
> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
> zipWith (*) [1,2,3] [4,5,6]
[4,10,18]
```

It's the eighth result provided by Hoogle when queried with your type

```
(a -> a -> a) -> [a] -> [a] -> [a]
```

Moreover, when you need to implement your own function, use `list !! index`

only as a last resort, since it usually leads to a bad performance, having a cost of `O(index)`

. Similarly, `length`

should be used only when necessary, since it needs to scan the whole list.

In the `zipWith`

case, you can avoid both and proceed recursively in a natural way: it is roughly implemented as

```
zipWith _ [] _ = []
zipWith _ _ [] = []
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
```

Note that this will only recurse as much as needed to reach the end of the shortest list. The remaining part of the longer list will be discarded.