import qualified Data.Map as M map_reduce :: ( Ord ki, Ord ko ) => ( (ki, vi) -> [(ko,vm)] ) -- ^ distribute -> ( ko -> [vm] -> vo ) -- ^ collect -> M.Map ki vi -- ^ eingabe -> M.Map ko vo -- ^ ausgabe map_reduce distribute collect input = M.mapWithKey collect $ M.fromListWith (++) $ map ( \ (ko,vm) -> (ko,[vm]) ) $ concat $ map distribute $ M.toList $ input