I'm looking to filter a traversal, then select the last element to use with over
.
e.g. something like this (but which will actually compile):
[1,2,3,4] & traverse . filtered even . _last +~ 10
> [1,2,3,14]
Any ideas?
P.S. I'm aware that filtered
is only valid when not affecting the number of elements in the traversal.
The actual use case I'm performing is to select only the lowest level of a recursive uniplate
traversal that matches some predicate; if you have other ideas of how to do this I'd love to hear them!
This isn't really an answer, just a follow-up to @Gurkenglas that's too big for a comment. Note that @Gurkenglas's answer:
let t = partsOf (traverse . filtered even) . _last
may look like a Traversal, but it isn't, even if you maintain the element count, because it violates the second Traversal law (for obvious reasons):
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
For it to be a traversal, you have to maintain both the element count and the filtering property as invariants.
Whether this will matter for your application, I don't know, but just be aware that partsOf
comes with these sorts of caveats, and the documentation misleadingly suggests that the result of partsOf
will be a Lens if you maintain the element count. (That's true for partsOf each
, the example given in the documentation, but not in general.)
[1,2,3,4] & partsOf (traverse . filtered even) . _last +~ 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With