module Main where import qualified Control.MapReduce.Simple as MR import qualified Control.Foldl as FL ints n = take n [1 ..] multipleOf n x = (x `mod` n) == 0 onlyEven = MR.filterUnpack even -- a filter andTwice x = [x, 2 * x] -- a "melt" withTwice :: MR.Unpack Int Int withTwice = MR.Unpack andTwice groupByMultOf3 = MR.assign (multipleOf 3) realToFrac -- An example using the function version addAll :: (Foldable f, Num a) => f a -> a addAll = FL.fold FL.sum reduceSum = MR.foldAndLabel FL.sum ((,)) reduceSum' = MR.processAndLabel addAll (,) reduceMean = MR.foldAndLabel FL.mean ((,)) -- sum of all even ints, grouped by whether or not they are mutliples of 3 sumsF = MR.mapReduceFold onlyEven groupByMultOf3 reduceSum sumsF' = MR.mapReduceFold onlyEven groupByMultOf3 reduceSum' -- mean of all even ints, grouped by whether or not they are mutliples of 3 meansF = MR.mapReduceFold onlyEven groupByMultOf3 reduceMean -- loop over initial list once but group each time sumsAndMeansF = (,) <$> sumsF <*> meansF -- loop over initial list once and group only once. sumAndMeanEachF = MR.mapReduceFold onlyEven groupByMultOf3 ((,) <$> reduceSum <*> reduceMean) -- sum and mean of all ints--and twice each int--grouped by whether or not they are multiples of 3. sumAndMeanWithTwiceF = MR.mapReduceFold withTwice groupByMultOf3 ((,) <$> reduceSum <*> reduceMean) {- We combine all the folds we want to do into one fold. So we loop over the input list only once here. We group it for each fold. But the last two, sumAndMeanEach and sumAndMeanWithTwice shows how we can avoid that as well. -} main :: IO () main = do let (s, s', m, sm, sme, smd) = MR.fold ( (,,,,,) <$> sumsF <*> sumsF' <*> meansF <*> sumsAndMeansF <*> sumAndMeanEachF <*> sumAndMeanWithTwiceF ) (ints 100) putStrLn $ "Sums: " ++ show s putStrLn $ "Sums': " ++ show s' putStrLn $ "Means: " ++ show m putStrLn $ "Sums & Means: " ++ show sm putStrLn $ "Sum & Mean of each: " ++ show sme putStrLn $ "Sum & Mean of all plus doubles: " ++ show smd {- Output: Sums: [(False,1734.0),(True,816.0)] Sums': [(False,1734.0),(True,816.0)] Means: [(False,51.0),(True,51.0)] Sums & Means: ([(False,1734.0),(True,816.0)],[(False,51.0),(True,51.0)]) Sum & Mean of each: [((False,1734.0),(False,51.0)),((True,816.0),(True,51.0))] Sum & Mean of all plus doubles: [((False,10101.0),(False,75.38059701492539)),((True,5049.0),(True,76.5))] -}