If I am interpreting your question correctly, you are saying that you would like a way to apply your function to a list of indices instead of a single index at a time.
The simplest way I can thing of to do this would be to create another function called
deleteElems instead of deleteElem (notice the trailing s.)
deleteElems would be of type [Int] -> [a] -> [a] and it would call on every index.
NOTE: See UPDATE at the bottom for the correct solution (I am leaving this part here so others may learn from my original attempt to solve the problem and why it is incorrect.)
Here is one way to do it:
deleteElems xs zs = foldr (\x z -> deleteElem x z) zs xs
which can be shortened to:
deleteElems xs zs = foldr deleteElem zs xs
Prelude> deleteElems [2,3] [1..10]
[1,4,5,6,7,8,9,10]
or from your example:
Prelude> map (deleteElems [2,3]) [["hello", "whatever", "foo", "bar"], ["hello", "whatever", "foo", "bar"], ["hello", "whatever", "foo", "bar"], ["hello", "whatever", "foo", "bar"]]
[["hello","bar"],["hello","bar"],["hello","bar"],["hello","bar"]]
deleteElems uses foldr to repeatedly call deleteElem to remove the indices in xs from zs. For a more in depth explanation of foldr, see How does foldr work?.
UPDATE:
as per comments the above implementation of deleteElems is actually incorrect because when given a list of indices, say [2,4,6], it will first remove index 2, return a new list, then remove index 4 on the new list and return a newer list, then remove index 6 on the newer list. This process is not commutative, meaning changing the order of the indices, or giving deleteElems the indices [6,4,2] will not do the same thing.
I a way to get the anticipated behaviour (removing the given indices from the original list) using the intersect function from Data.List:
deleteElems xs zs = foldr1 intersect $ map ($ zs) $ map deleteElem xs
This new version of deleteElems applies deleteElem using each index in xs, creating a list of length xs number of lists of deleteElem functions curried to each specific index. Then the map ($ zs) applies each of the curried deleteElem functions to zs, yielding a list of lists, where each inner list is just deleteElem applied to one of the indices and zs. Finally, we use intersect from Data.List to find the list with all correct elements removed.
Also, I still definitely recommend checking out How does foldr work?.