私があなたの質問を正しく解釈している場合、一度に 1 つのインデックスではなく、インデックスのリストに関数を適用する方法が必要だと言っています。
これを行う最も簡単な方法は、
deleteElems代わりに呼び出される別の関数を作成することですdeleteElem(末尾のs.)
deleteElemsタイプ[Int] -> [a] -> [a]になり、すべてのインデックスで呼び出されます。
注: 正しい解決策については、下部にある更新を参照してください (この部分はここに残しておきます。これにより、他の人が問題を解決しようとする最初の試みと、それがなぜ間違っているのかを学ぶことができます)。
これを行う1つの方法は次のとおりです。
deleteElems xs zs = foldr (\x z -> deleteElem x z) zs xs
これは次のように短縮できます。
deleteElems xs zs = foldr deleteElem zs xs
Prelude> deleteElems [2,3] [1..10]
[1,4,5,6,7,8,9,10]
またはあなたの例から:
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からのインデックスを削除するためfoldrに繰り返し呼び出すために使用します。の詳細な説明については、「foldr はどのように機能しますか?」を参照してください。.deleteElemxszsfoldr
アップデート:
コメントによると、上記の実装deleteElemsは実際には正しくありません。たとえば[2,4,6]、インデックスのリストが与えられると、最初に index2を削除4し、新しいリストを返し、次に新しいリストのインデックスを削除して新しいリストを返し、新しい6リストのインデックスを削除するためです。リスト。このプロセスは交換可能ではありません。つまり、インデックスの順序を変更したり、インデックスを指定したりしても、同じことは行われません。deleteElems[6,4,2]
関数 fromを使用して、予想される動作 (指定されたインデックスを元のリストから削除する)を取得する方法です。intersectData.List
deleteElems xs zs = foldr1 intersect $ map ($ zs) $ map deleteElem xs
この新しいバージョンのは、 の各インデックスを使用してdeleteElems適用され、特定の各インデックスにカリー化された関数のリストの数のリストを作成します。次に、はカリー化された各関数をに適用し、リストのリストを生成します。各内部リストは、インデックス および の 1 つに適用されます。最後に、fromを使用して、すべての正しい要素が削除されたリストを見つけます。deleteElemxslength xsdeleteElemmap ($ zs)deleteElemzsdeleteElemzsintersectData.List
また、チェックアウトすることをお勧めします どうやってfoldrが機能するのですか?.