2017-12-23 16 views
-3
dropnth' :: [a] -> Int -> [a] 
dropnth' xs n = foldl (\a b -> if (last a) == xs!!n then a else b ++ []) [head xs] xs 

私はfoldlを使用してこの「リストのn番目の要素を削除する」問題を解決しようとしていましたが、エラーが発生しています。どうやってやるの?foldlを使用してリストのn番目の要素を削除するにはどうすればよいですか?

エラー: The error

+6

"私はエラーが発生しました"非常に有用ではありません、画像ではなく、あなたのポストに完全なエラーメッセージを投稿してください。 – Zpalmtree

+3

「head、tail、!!」は危険なほど部分的なので、可能な場合は常に避ける方が良いです。 – chi

+0

この目的のために 'foldl'を使うべきではありません。コードの効率が悪く、怠惰でないコードを取得することが保証されています。あなたは 'foldr'でもっとうまくいくことができますが、それについて少し賢明にしなければなりません。 – dfeuer

答えて

4

aは、おそらくあなたはすでに落下しないことを決定しました要素です。 aの最後の要素ではなく、次の要素がxs(おそらくb)にドロップするかどうかを決定する必要があります。

b ++ []は、おそらくあなたの代わりにリストaに追加し、要素bをドロップしないことを決定したことを表現するためのものです。これは実際にはa ++ [b]と書かれています。

これは、私は、少なくともコンパイルされ、コードのこの作品を書くことができます:

dropnth' :: Eq a => [a] -> Int -> [a] 
dropnth' xs n = foldl (\a b -> if b == xs!!n then a else a ++ [b]) [head xs] xs 

xs!!nxsのn番目の要素を見つけ、そしてそれと比較することは、何かの値がそれと同じであるかどうかではない決めるでしょう何かの位置。 Eq aに注目してください。これは、リストの値を比較していることを示しています。 foldlは、zip [0..]など、どこかからエントリの位置を取得する必要があります。リストの最後に要素を追加

dropnth' :: [a] -> Int -> [a] 
dropnth' xs n = foldl (\a (i, b) -> if mod i n == 0 then a else a ++ [b]) [head xs] (zip [0..] xs) 

は、リスト全体を再構築しなければなりません。最後からリストを構築する方がはるかに効率的です。しかし、このケースでは、ユースケースに対してより特殊なリスト操作を使用することさえできます。

dropnth' :: [a] -> Int -> [a] 
dropnth' xs n = [b | (i, b) <- zip [0..] xs, mod i n > 0] 

最初の要素も削除するようになりました。おそらくそれはあなたが望むものですか?または、zip[1..]とし、すべての十字線を1つ左にシフトすることもできます。

通常、Int -> [a] -> [a]のような署名を入力してください。

関連する問題