2017-09-24 18 views
2

私はリストを持っているとしましょう。[A]ある述語を満たす場合、リストの特定の要素を更新したい。しかし、そのような要素がなければ、最初にリストに要素を追加したいと思います。私の現在の解決策は、そこにない場合はリストに要素を挿入する関数を手動で記述し、要素を更新するにはfiltered Traversalを使用することです。このように:'レンズ'がない場合、リストに要素を追加するにはどうすればいいですか?

もっと良い(もっと短い、より慣用的な)ソリューションがあるのだろうか?可能であれば、私はmicrolensパッケージファミリだけを使用するソリューションを感謝します。

+0

@chepner非常に近いが厳密ではない。ご覧のとおり、私はリストを使用しているので、効率は私の最優先事項ではありません。私のソリューションはすでに効率的だと思うかもしれませんが、たぶん1つのトラバーサルリストしか使用しないでしょう。私はより短い形式(効率の大きな損失なし)が欲しい。そして、私はレンズを使用するソリューションに興味があります(レンズなしで自分でできます)。違いは、あなたのフォームの 'myUpdate'は、フォームの中で' map myUpdate'がリストのすべての要素を変更する間、要素を変更するかどうかをチェックすべきです。しかしあなたのアイデアは私が望むものに非常に近いです。 – Shersh

+0

ああ、申し訳ありません。私はあなたが本当に望んでいたものを理解して、私のコメントを削除するのを忘れました。 – chepner

答えて

0

あなたはそれを少し短くするhasを使用することができるはずです。

functionIWantToWrite :: [A] -> [A] 
functionIWantToWrite = modifyItem . addEmptyItem 
    where 
    _items = filtered myPredicate 
    addEmptyItem list | has _items list = list 
         | otherwise  = item : list 
    modifyItem = each . _items %~ myUpdate 

あなたが本当にそれを短くしたい場合は、あなただけのMonoid m => Applicative (m,)インスタンスを使用して、単一のトラバーサルとしてそれを得ることができるかもしれませんそういうものがあります。

関連する問題