Datasheet
Lambda Calculus (Briefl y)
x
21
static Op<T1, Op<T2, U>> Curry<T1, T2, U>(Op<T1, T2, U> fn)
{
return delegate(T1 arg1)
{
return delegate(T2 arg2)
{
return fn(arg1, arg2);
};
};
}
static void MoreMathExamples()
{
int result = Add(2, 3);
Operation add2 = delegate(int l, int r) { return l + r; };
int result2 = add2(2, 3);
DelegateOp add3 = delegate(int l)
{
return delegate(int r)
{
return l + r;
};
};
int result3 = add3(2)(3);
Func<int,Func<int, int>> add4 =
delegate(int l)
{
return delegate(int r)
{
return l + r;
};
};
int result4 = add4(2)(3);
Op<int, int, int> add5 =
delegate(int l, int r) { return l+r; };
int result5 = add5(2, 3);
Op<int, Op<int, int>> curriedAdd = Curry(add5);
int result6 = curriedAdd(2)(3);
}
It’s horribly obtuse, and no sane C# developer would write add this way…unless they wanted to
build up chains of functions calling functions in a highly generic way:
Op<int, int> increment = curriedAdd(1);
int result7 = increment(increment(increment(2)));
Although it seems awkward to think about at fi rst, composing functions in this way means a new
level of reusability has opened up, that of taking operations (methods) and breaking them into
smaller pieces that can be put back together in new and interesting ways.
The most obvious use of this is to “pipeline” functions together in various ways, permitting reuse
of behavior at a level previously unheard of in the object-oriented space. Functionality can now be
c01.indd 21c01.indd 21 10/1/2010 3:20:38 PM10/1/2010 3:20:38 PM










