Search code examples
haskell

General approach for combining multiple foldrs over the accumulator type?


Recently I've come up with an idea for a function:

gridFoldr :: (a -> Grid -> Grid) -> [a] -> Grid -> Grid
gridFoldr f g xs = foldr f xs g

So I can easily combine multiple grid computations using the plain (.) operator:

let grid' = gridFoldr gridOp1 args1 . gridFoldr gridOp2 args2 $ myGrid

But I have a feeling that I'm missing some general haskell concept for using a similar approach without introducing a new function. Am I right? Is there some standard function / package / or maybe some clever Monad to do the task?


Solution

  • It looks like you are interested in "grid updates", i.e. in functions Grid -> Grid. This type is isomorphic to Endo Grid, which is a well-known monoid.

    So, your function is similar to

    foldGrid :: (a -> Endo Grid) -> [a] -> Endo Grid
    foldGrid f = mconcat . map f
    

    or even, exploiting more libraries

    foldGrid = foldMap
    

    Indeed, foldMap is a generalization of your function.

    foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m