title: RamdaJS reduceBy() in Haskell using recursion-schemes
body: <p>I have the following code using <code>recursion-schemes</code> library:</p>
  
  <pre><code>{-# 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 =&gt;
       (ListF t a -&gt; a) -&gt; (t -&gt; k) -&gt; ListF t (M.Map k a) -&gt; M.Map k a   
  fooAlgebra valueAlgebra keyFn = \case
      Nil -&gt; M.empty
      Cons elt acc -&gt; M.alter 
           (Just . (valueAlgebra . Cons elt) . fromMaybe (valueAlgebra Nil)) 
           (keyFn elt)
           acc
  </code></pre>
  
  <p>Use as <code>let countBy = reduceBy (\case Nil -&gt; 0 ; Cons a b -&gt; succ b) id in countBy [42,5,5,8,8,8]</code>. The code mimics <a href="http://ramdajs.com/docs/#reduceBy" rel="nofollow noreferrer">http://ramdajs.com/docs/#reduceBy</a></p>
  
  <p>Is there a better way to implement <code>reduceBy</code> using <code>recursion-schemes</code>? The <code>alter</code> arguments seem fragile, and is <code>cata</code> really appropriate there? I heard that some things are implementable both as <code>ana</code> and <code>cata</code>.</p>