using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace Foldables.List.Compose
public static void Main()
var compositeList = new List<List<int>>() { new List<int>() { 1, 2 }, new List<int>() { 3, 4 } ,new List<int>() {5, 10 }};
var compositeFoldResult = compositeList.FoldT(monoid: (() => 0, (x, y) => x + y));
Console.WriteLine( "total sum:"+compositeFoldResult);
public static partial class funcExtensions
public static T1 MatchWith<T, T1>(this List<T> @this, (Func<T1> Empty, Func<T, List<T>, T1> Cons) algebra) =>
algebra.Cons(@this[0], @this.GetRange(1, @this.Count - 1));
public static T Fold<T>(this List<T> @this, (Func<T> empty, Func<T, T, T> concat) monoid) =>
@this.MatchWith(algebra: (
Cons: (v, r) => monoid.concat(v, r.Fold(monoid))
public static T FoldT<T>(this List<List<T>> @this, (Func<T> empty, Func<T, T, T> concat) monoid)
=> @this.Select(x => x.Fold(monoid)).ToList().Fold(monoid);