Suppose that (from the Lens library) I have
fold1 :: Fold s a
fold2 :: Fold s a
and I want to combine these in such a way that
toListOf (combine fold1 fold2) s == toListOf fold1 s ++ toListOf fold2 s
What is the simplest implementation of combine? (It's of course possible just to manually implement it in terms of toListOf, or the like, but I suspect a more purely compositional implementation exists.)
It seems that the efficient implementation is simply
combine f1 f2 k s = f1 k s *> f2 k s
though it's also possible to go via the ReifiedFold, though that appears to use the maybe-less-efficient toListOf implementation:
combine f1 f2 = runFold (Fold f1 <> Fold f2)
It took me some time to understand why the apparently asymmetric *> sufficed.
You can use (<>) directly to combine the folds:
ghci> [1..4] ^.. (folded . filtered even <> backwards folded)
[2,4,4,3,2,1]
As I'm overtly assuming a Monoid instance rather than relying on Fold's Applicative constraint, the types are slightly different than the ones in your (*>)-based solution. That won't matter in practice, though.
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