您的位置:首页 > 其它

如何用函数表示数(五)其他运算

2013-07-17 22:24 204 查看
有了增1和0,我们就可以表示出所有的数了。事实上,这种用函数计数的方法叫做church numeral,发明者是阿隆佐.邱奇,听说过此名字的人可能不多,此人发明了lambda算子,为图灵的导师,奠定了现代计算机理论基础的图灵机正是lambda运算的一种表现方式。因此此人可以被称为咱们程序员的祖师爷,也不为过。

除了增1之外,该计数法还有其他的运算方式,下面一一进行陈列和解说。

加法

function add(n){
return function(m){
return function(f){
return function(x){
return n(f)(m(f)(x));
}
}
}
} printduck(add(two)(three));
别晕,拆开来看就能看得清楚。

加法虽然嵌套了四层,这是因为加法是双目运算,除了表现出加法结果的f和x之外,还有两个被加数要加进来:

function add(n){
return function(m){
return function(f){
return function(x){
part1 = m(f)(x);//execute f(x) m times;
return n(f)(part1);//execute f(x) n times,so tolally m+n tiimes;
}
}
}
}


前面说过,形如n(f)(x)表示把f(x)执行n次。那么m(f)(x),表示执行m次f(x),n(f)(m(f)(x)),表示执行m+n次f(x),其结果就是表示出了m+n。此外,m和n中任意一个为0,都不会影响到另一半得出结果。

乘法

function multi(n){
return function(m){
return function(f){
return function(x){
return n(m(f))(x);
}
}
}
}

printduck(multi(two)(three));
弄懂了前面的加法,相信乘法是很好懂的。n(m(f))(x)表示把m(f)(x)执行n次,而m(f)(x)又表示表示把f(x)执行m次,因此等于执行m x n次f(x),乘法得以表示。此外n和m中有任何一个为zero都会让最终结果变为0.

真正销魂的是

指数算法:

function exp(m){//m^n
return function(n){
return function(f){
return function(x){
return n(m)(f)(x);
}
}
}
}
printduck(exp(three)(two));


相信看得懂的人不多,我努力做些解释看能不能帮助大家理解.

当n等于zero时,该式等于zero(m)(f)(x),根据zero的定义,zero(m)(f)=f.该试等于f(x)。因此不论m等于几,f(x)一定只被执行一次,相当于0的任意次方都等于1.

当n为大于0的数时,n(m)(f)(x) 相当于incr(n-1)(m)(f)(x)
再套用incr公式得到m(n-1(m)(f))(x)
正好可以套用前面的乘法公式n(m(f))(x),相当于把f(x)执行m*(n-1(m))次
而n-1(m)又可以转化为m*(n-2(m))
经过n次转换后,最终得到m*m*m……*m*(zero(m)),前面已经证明zero(m)=1
因此n(m)(f)(x)等于执行f(x)m的n次方次,得证。

思考&后记:

本篇文章只是展示了函数式编程方法的冰山一角,希望你看完这篇文章后可以体会到函数式本身的灵活和强大,而不仅仅是找到了一种新奇好玩的表示数的方法。留下几个问题给大家思考:

可不可以设计一个函数叫repeat(n,f)或repeat(n),它不仅能够重复执行一个任务n遍,还能够像上面的函数一样本身也具备叠加等数的性质?比如repeat(n,repeat(n,repeat(n,...)))。

在示例中用到的f和x两个函数,它们都具备入参x,入参x能否省略,为什么?

前文中提到n(f)(x)中,x从来不被执行。因此,在x处传入任何东西都是可以的。这句话是对还是不对?为什么?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐