Thursday, May 15, 2014

Partial apply in C#

Partial apply by Wikipedia:

In computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. Given a function \scriptstyle f \colon (X \times Y \times Z) \to N , we might fix (or 'bind') the first argument, producing a function of type  \scriptstyle\text{partial}(f) \colon (Y \times Z) \to N . Evaluation of this function might be represented as f_{partial}(2, 3). Note that the result of partial function application in this case is a function that takes two arguments.

In short, that means you define (bind) some of the possible arguments and leave some to be filled in later (free).

Scala

def sum(a:Int, b:Int, c:Int):Int = a+b+c  //> sum: (a: Int, b: Int, c: Int)Int
sum(1,2,3)                                //> res11: Int = 6

def sum1 = sum(1, _:Int, _:Int)           //> sum1: => (Int, Int) => Int
sum1(2,3)                                 //> res12: Int = 6

def sum2 = sum(_:Int, 2, _:Int)           //> sum2: => (Int, Int) => Int
sum2(1,3)                                 //> res13: Int = 6

sum1 binds the first parameter but the other two parameters are free. As you can see from the result it gets translated to a lambda with two parameters.

sum2 binds the second parameter. The result is the same, a lambda with two parameters.

C#

C# has no built-in operator for applying a function, so we have to write the lambdas directly.

readonly Func sum = (x, y, z) => x + y + z;

[Fact]
public void Sum()
{
    var result = sum(1, 2, 3);

    Assert.Equal(6, result);
}

[Fact]
public void Sum_PartialApply_FirstParam()
{
    Func sum1 = (y, z) => sum(1, y, z);

    var result = sum1(2, 3);

    Assert.Equal(6, result);
}

[Fact]
public void Sum_PartialApply_SecondParam()
{
    Func sum2 = (x, z) => sum(x, 2, z);

    var result = sum2(1, 3);

    Assert.Equal(6, result);
}