map_reduce :: ( Ord ki, Ord ko )
=> ( (ki, vi) -> [(ko,vm)] ) -- ^ distribute
-> ( ko -> [vm] -> Maybe vo ) -- ^ collect
-> Map ki vi -- ^ eingabe
-> Map ko vo -- ^ ausgabe
map_reduce distribute collect input
= M.map ( \ ( Just x ) -> x )
$ M.filter isJust
$ M.mapWithKey collect
$ M.fromListWith (++)
$ map ( \ (ko,vm) -> (ko,[vm]) )
$ concat $ map distribute
$ M.toList $ input