using System; using System.Diagnostics; using System.Threading; using System.Runtime.CompilerServices; using System.Linq; using System.Threading.Tasks; class Program { static void Main(string[] args) { // Unfortunately type inference and method group conversion // aren't always happy together, so I've split them into // two statements. Func function = SampleFunction; // Call the method directly string result1 = function(1, 2, 3); Console.WriteLine("Result from normal call: {0}", result1); // Func partial = ApplyPartial(function, 1); string result2 = partial(2, 3); Console.WriteLine("Result from immediate partial application: {0}", result2); Func partial1 = ApplyPartial(function, 1); Func partial2 = ApplyPartial(partial1, 2); Func partial3 = ApplyPartial(partial2, 3); string result3 = partial3(); Console.WriteLine("Result from partial application in stages: {0}", result3); // Call via currying Func>> f1 = Curry(function); Func> f2 = f1(1); Func f3 = f2(2); string result4 = f3(3); Console.WriteLine("Result from currying in stages: {0}", result4); // Or to do make all the calls together... var curried = Curry(function); string result5 = curried(1)(2)(3); Console.WriteLine("Result from currying in one go: {0}", result5); } static string SampleFunction(int a, int b, int c) { return string.Format("a={0}; b={1}; c={2}", a, b, c); } static Func ApplyPartial (Func function, T1 arg1) { return (b, c) => function(arg1, b, c); } static Func ApplyPartial (Func function, T1 arg1) { return arg2 => function(arg1, arg2); } static Func ApplyPartial (Func function, T1 arg1) { return () => function(arg1); } static Func>> Curry (Func function) { return a => b => c => function(a, b, c); } }