Thursday, May 8, 2014

Currying in Scala and C#

Currying is an interesting and powerful functional programming concept. Interestingly currying can be used in C# as well.

The usual approach

Let's define a simple add function that sums two numbers in C#:

[Fact]
public void SimpleAdd_AsInlineFunction_WithLambda()
{
    Func<int, int, int> add = (x, y) => x + y;
    var result = add(5, 7);
    Assert.Equal(12, result);
}

The same in Scala:

def add(x:Int,y:Int) = x+y                      //> add: (x: Int, y: Int)Int
add(5,7)                                        //> res0: Int = 12
Or with lambda:
def add_lambda = (x:Int,y:Int) => x+y           //> add_lambda: => (Int, Int) => Int
add_lambda(5,7)                                 //> res1: Int = 12

Currying

Now Implement the same function in C#, but this time with currying:

[Fact]
public void CurryingAdd()
{
    Func<int, Func<int, int>> add = x => y => x + y;
    var result = add(5)(7);
    Assert.Equal(12, result);
}

In Scala:

def add_lambda_currying(x:Int) = (y:Int) => x+y //> add_lambda_currying: (x: Int)Int => Int
add_lambda_currying(5)(7)                       //> res2: Int = 12

With simplified Scala syntax:

def add_currying(x:Int)(y:Int): Int = x+y       //> add_currying: (x: Int)(y: Int)Int
add_currying(5)(7)                              //> res3: Int = 12

Partial apply

Now let’s suppose I want to bind the first parameter to a concrete value (bound) but I want to keep the second parameter unbounded (free).

This is the way in C#:

[Fact]
public void CurryingAdd_Add5()
{
    Func> add = x => y => x + y;
    var add5 = add(5);
    
    var result1 = add5(7);
    Assert.Equal(12, result1);

    var result2 = add5(122);
    Assert.Equal(127, result2);
}

The same idea in Scala:

def add5_lambda_currying = add_lambda_currying(5)  //> add5_lambda_currying: => Int => Int
add5_lambda_currying(7)                         //> res3: Int = 12

def add5_currying = add_currying(5) _           //> add5_currying: => Int => Int
add5_currying(7)                                //> res5: Int = 12

In case of the add5_currying example please notice the underscore (_) at the end of the expression. That means partial apply and indicates that I don’t want to bind the second parameter. There is no need for such indicator with lambda syntax.