foldl
foldl copied to clipboard
How to replicate a Fold inside sublists?
I was looking for a way to compute the mean of a list of lists "by column", i.e. compute the mean of the first elements of the sublists, the second elements, etc. I looked for a way to transform Fold.mean :: Fold Double Double
into a Fold [Double] [Double]
. I couldn't find a way so I wrote the function below. My question is: did I miss a better, perhaps applicative-style way to do it?
foldZ :: Fold a b -> Fold [a] [b]
foldZ (Fold s i e) =
Fold (\xs as -> zipWith s xs as)
(repeat i)
(\xs -> fmap e xs)
@guillaumecherel: No, there isn't a better approach that I'm aware of when the number of list elements is not fixed.
If there were a fixed number of elements (such as a 2-tuple pretending to be a list of 2 elements), then the solution would be:
(,) <$> handles _1 mean <*> handles _2 mean
:: (Fractional a, Fractional b) -> Fold (a, b) (a, b)
Does it look to you like an addition to the folds worth doing a pull request?
@guillaumecherel: Yeah!
What I just noticed is that this can actually be generalized to any Applicative
, like this:
nest :: Applicative f => Fold a b -> Fold (f a) (f b)
nest (Fold s i e) =
Fold (\xs as -> liftA2 s xs as)
(pure i)
(\xs -> fmap e xs)
foldZ
then becomes the special case where f = ZipList
Right, nice! I'll prepare something with this.