Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composing two folds

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.)

like image 744
Louis Wasserman Avatar asked Oct 24 '25 15:10

Louis Wasserman


2 Answers

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.

like image 132
Louis Wasserman Avatar answered Oct 27 '25 10:10

Louis Wasserman


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.

like image 21
duplode Avatar answered Oct 27 '25 09:10

duplode



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!