[Haskell-cafe] Multi groupby with foldl' and Map.insertWithKey

Jan-Willem Maessen jmaessen at alum.mit.edu
Wed Dec 28 18:40:17 UTC 2016


On Wed, Dec 28, 2016 at 8:07 AM, Olaf Klinke <olf at aatal-apotheke.de> wrote:

> I'd say the cleanest way to go is to split your Info data structure into
> an intermediate key and a value part like so:
>
> type Key = String
> data Value = Value {count :: !Int, healthTopics :: ![String]}
>
> keyvalue :: Info -> (Key,Value)
> keyvalue (Info _ h k) = (k,Value 1 [h])
>
> and give Value a Monoid instance:
>
> instance Monoid Value where
>   mempty = Value 0 []
>   mappend (Value c s) (Value c' s') = Value (c+c') (s++s')
>
> (Or you could use (Sum Int) instead of Int and have
> type Value = (Sum Int,[String]).
> Then the Monoid instance is derived for you.)
>

A caution on this alternative: the first component of the tuple won't be
strict enough and you'll leak space.  I think the proposed solution is
better.  Note that you *don't* necessarily need the strictness annotation
on healthTopics – this shifts around when the list append gets run but
won't change space much.

-Jan-Willem Maessen


> Now you can transform a list of Infos into a Map using a generic function:
>
> makeMap :: [Info] -> M.Map Key Value
> makeMap = M.fromListWith mappend . map keyvalue
>
> Semantically, it's pretty identical to ALeX Kazik's suggestion of using
> foldl' and alter. Internally, fromListWith uses a strict fold, so
> strictness should be the same as using foldl'.
>
> Olaf
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20161228/e34c5de0/attachment.html>


More information about the Haskell-Cafe mailing list