I have the following code using recursion-schemes library:
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeFamilies #-}
import Data.Functor.Foldable
import Data.Maybe
import qualified Data.Map as M
reduceBy valueAlgebra keyFn = cata $ fooAlgebra valueAlgebra keyFn
fooAlgebra
:: Ord k =>
(ListF t a -> a) -> (t -> k) -> ListF t (M.Map k a) -> M.Map k a
fooAlgebra valueAlgebra keyFn = \case
Nil -> M.empty
Cons elt acc -> M.alter
(Just . (valueAlgebra . Cons elt) . fromMaybe (valueAlgebra Nil))
(keyFn elt)
acc
Use as let countBy = reduceBy (\case Nil -> 0 ; Cons a b -> succ b) id in countBy [42,5,5,8,8,8]. The code mimics http://ramdajs.com/docs/#reduceBy
Is there a better way to implement reduceBy using recursion-schemes? The alter arguments seem fragile, and is cata really appropriate there? I heard that some things are implementable both as ana and cata.
fmapa catamorphism (a fold, really) for each group. - danidiazvalueAlgebra? Seems a good idea. Now I pass the algebra toalter, which accepts its church-encoded version. And the decoding is painful. - nponeccop