• Currying Function C#

    by  • April 7, 2013 • .Net, Journal, Programming • 0 Comments

    A while ago I did a post about Lambda calculus in C#, mainly focusing on how you can implement the concept of Y combinators. Y combinators are one of the simplest fixed point combinators in Lambda calculus, and was discovered by a Mr Curry. One of the other interesting concepts of Lambda calculus is the concept of ‘Currying’.

    Heres a quick foray back at Y Combinator:

    ///
    /// One-argument Y-Combinator.
    ///
    public static Func<T, TResult> Y<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> F)
    {
    	return t => F(Y(F))(t);
    }
    
    ///
    /// Two-argument Y-Combinator.
    ///
    public static Func<T1, T2, TResult> Y<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> F)
    {
    	return (t1, t2) => F(Y(F))(t1, t2);
    }
    
    ///
    /// Three-arugument Y-Combinator.
    ///
    public static Func<T1, T2, T3, TResult> Y<T1, T2, T3, TResult>(Func<Func<T1, T2, T3, TResult>, Func<T1, T2, T3, TResult>> F)
    {
    	return (t1, t2, t3) => F(Y(F))(t1, t2, t3);
    }
    
    ///
    /// Four-arugument Y-Combinator.
    ///
    public static Func<T1, T2, T3, T4, TResult> Y<T1, T2, T3, T4, TResult>(Func<Func<T1, T2, T3, T4, TResult>, Func<T1, T2, T3, T4, TResult>> F)
    {
    	return (t1, t2, t3, t4) => F(Y(F))(t1, t2, t3, t4);
    }
    

    Currying is the concept of integrating an argument of a function into a new function with the argument built in.

    Take the following maths equation:

    f(a, b, c) where f = a + b + c

    so

    f(1, 2, 3) would mean f = 6

    The concept of currying takes the argument and effectively hardcoding it, so take a look again at the previous function.

    Currying f(1, b, c) would produce a new function f1(b, c) where f1 = 1 + b + c

    This idea is important of things like constructors or overloading functions, where some arguments may be fixed.

    Currying in C# lambda calculus looks like the following:

    // Curry first argument
    public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> F)
    {
    	return t1 => t2 => F(t1, t2);
    }
    
    // Curry second argument.
    public static Func<T2, Func<T1, TResult>> Curry2nd<T1, T2, TResult>(Func<T1, T2, TResult> F)
    {
    	return t2 => t1 => F(t1, t2);
    }
    
    // Uncurry first argument.
    public static Func<T1, T2, TResult> Uncurry<T1, T2, TResult>(Func<T1, Func<T2, TResult>> F)
    {
    	return (t1, t2) => F(t1)(t2);
    }
    
    // Uncurry second argument.
    public static Func<T1, T2, TResult> Uncurry2nd<T1, T2, TResult>(Func<T2, Func<T1, TResult>> F)
    {
    	return (t1, t2) => F(t2)(t1);
    }
    

    About

    Software engineer. Tea drinker

    http://MrPfister.com

    Leave a Reply

    Your email address will not be published. Required fields are marked *