前面说到了C#的泛型委托和闭包函数,在函数是程序设计里还有一个重要特征是柯里化...
柯里化就是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。用F#来举个例子:
> let sum x y = x + y;;
val sum : x:int -> y:int -> int
声明了一个叫sum接受三个参数并返回一个整数的函数。
> let sumwith5 y = sum 5;;
val sumwith5 : y:'a -> (int -> int)
通过这个声明,我们定义了一个接受两个参数并返回一个整数的函数。其实我们可以看到,函数的特征是y:'a -> (int -> int)
而不是y:int -> int
,而函数体部分为sum 5
,感觉就是调用了sum这个函数,并且把x
赋值为5后剩下的y
由参数输入。
嗯,这个就叫做柯里化。在F#里,我们用这项技术简直游刃有余,轻轻松松就能搞一些新的函数出来,尽管这些函数是从别的函数截取的一截(更类似蹭了一节)...
那么C#能不能做这个呢...当然阔以...只不过写起来稍微嗨皮一点...就像这样:
Func<Int32, Func<Int32, Int32>> sum = x => y => x + y;
Func<Int32, Int32> sumwith5 = sum (5);
再次说一下,由于C#不是以函数式为主的程序设计语言,所以写起来自然没有F#那么自然。并且如果我们调用F#里的sum
函数只需要sum 5 6
就可以了,但是C#需要这样写:
sum (5) (6);
既然不自然特么还写个屌毛啊...
其实我们可以写一个方法来实现简单的柯里化,比如:
public static Func<T1, Func<T2, TR>> Curry<T1, T2, TR> (this Func<T1,T2,TR> Func) => a => b => Func (a, b);
我们实现sum
函数的柯里化只需要sum.Curry ();
就可以了。当然C#不是以函数式程序设计的程序设计语言...
你到底想说什么##
客官要不要来学学F#呢?