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 = 12Or 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.
No comments:
Post a Comment