using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
public interface IMonoid<T>
public class SumDecimal : IMonoid<double>
public double Concat(double x, double y) => x + y;
public double Empty => 0;
public static void Main()
var bigList = Enumerable.Range(1, 1000000);
Func<IEnumerable<int>, Func<int, IEnumerable<IEnumerable<int>>>> slice = list => size =>
var accumulation = new List<IEnumerable<int>>();
for (int i = 0; i < list.Count(); i += size)
accumulation.Add(list.Skip(i).Take(size));
Func<IEnumerable<IEnumerable<int>>, Func<IMonoid<double>, Func<Func<double, double>, double>>>
mapReduce = list => monoid => map =>
chunk.Select(Convert.ToDouble).Select(map).Aggregate(monoid.Empty, monoid.Concat)
).Aggregate(monoid.Empty, monoid.Concat);
var chunks = slice(bigList)(10000);
var sum = mapReduce(chunks)(new SumDecimal())(x => x*x*x);