2017-06-19 4 views
9

トラバースをフィルタリングし、最後に使用する要素をoverで選択します。最後の要素を越えたトラバース "

(実際にはコンパイルされます)

[1,2,3,4] & traverse . filtered even . _last +~ 10 
> [1,2,3,14] 

何か考えですか?

P.S. filteredは、トラバーサルの要素数に影響しない場合にのみ有効です。

私が実行している実際の使用例は、ある述語に一致する再帰的なuniplateトラバーサルの最低レベルのみを選択することです。あなたがこれを行う方法の他のアイデアを持っているなら、私はそれらを聞くのが大好きです!

+0

逆状態のモナド変換器をトラバースすることでこれを行う際に亀裂がありましたが、それは 'MonadFix m => Traversal 'sa - > LensLike' msa'はあまり有用ではありません - 'Const s'は' Monad'ではないので、あなたは値を入れてもらうことはできません。別のアプローチは、コレクションの長さを折りたたんで取得し、最後のインデックスまで状態を数えることです。効率を犠牲にして、MonadFixではなくMonadという制約を与えます。 @ Gurkenglasの回答のように、具体的なリストを通って行くのがおそらく最善の策だろう –

答えて

1

これは本当に答えではなく、コメントのために大きすぎる@Gurkenglasのフォローアップです。 Gurkenglasの答え@ことに注意してください。

let t = partsOf (traverse . filtered even) . _last 

トラバーサルのように見えるが、それはそれは(明白な理由のために)第二トラバーサル法に違反するので、あなたは、要素数を維持していても、いない場合があります。

それはトラバーサルを可能にするには
let f = Identity . succ 
[1,2,3,4] & fmap (t f) . t f -- yields [1,3,3,5] effectively 
[1,2,3,4] & getCompose . t (Compose . fmap f . f) 
           -- yields [1,2,3,6] effectively 

、あなたは要素が不変量などのフィルタリングプロパティを数える両方を維持する必要があります。

これはあなたのアプリケーションでは問題になるかどうか、私は知っているが、ちょうどpartsOfが警告のこれらの種類が付属しており、ドキュメントは誤解を招くあなたは要素を維持する場合partsOfの結果はレンズであることを示唆していることに注意していませんカウント。 (これはpartsOf eachの場合には当てはまりますが、一般的な説明ではありません)

2
[1,2,3,4] & partsOf (traverse . filtered even) . _last +~ 10 
関連する問題