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?.