I'm fetching a list of records from a webservice and generating reports based on that data. I'm currently using code similar to this:
let sorted = sortBy (comparing field1 <> comparing field2) records
let grouped = groupBy cmp sorted
where cmp x y = (field1 x) == (field1 y)
&& (field2 x) == (field2 y)
let subtotals = map subtot grouped
where subtot = foldl1 recsum
recsum x y = x { field3 = (field3 x) + (field3 y) }
Is there a less verbose way to accomplish this? It gets a bit cluttery, especially when grouping by multiple fields. Even just having a single function for sort+group would help. I thought of writing a function taking a list of field deconstructors like
sortAndGroup :: Ord v => [r -> v] -> [r] -> [[r]]
but that won't work when the fields have different types. Any ideas?