私があなたの質問を正しく解釈している場合、一度に 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 はどのように機能しますか?」を参照してください。.deleteElem
xs
zs
foldr
アップデート:
コメントによると、上記の実装deleteElems
は実際には正しくありません。たとえば[2,4,6]
、インデックスのリストが与えられると、最初に index2
を削除4
し、新しいリストを返し、次に新しいリストのインデックスを削除して新しいリストを返し、新しい6
リストのインデックスを削除するためです。リスト。このプロセスは交換可能ではありません。つまり、インデックスの順序を変更したり、インデックスを指定したりしても、同じことは行われません。deleteElems
[6,4,2]
関数 fromを使用して、予想される動作 (指定されたインデックスを元のリストから削除する)を取得する方法です。intersect
Data.List
deleteElems xs zs = foldr1 intersect $ map ($ zs) $ map deleteElem xs
この新しいバージョンのは、 の各インデックスを使用してdeleteElems
適用され、特定の各インデックスにカリー化された関数のリストの数のリストを作成します。次に、はカリー化された各関数をに適用し、リストのリストを生成します。各内部リストは、インデックス および の 1 つに適用されます。最後に、fromを使用して、すべての正しい要素が削除されたリストを見つけます。deleteElem
xs
length xs
deleteElem
map ($ zs)
deleteElem
zs
deleteElem
zs
intersect
Data.List
また、チェックアウトすることをお勧めします どうやってfoldrが機能するのですか?.