文档章节

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

ueharaai
 ueharaai
发布于 2013/07/17 22:24
字数 941
阅读 49
收藏 0

有了增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次方次,得证。


思考&后记:

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

  1. 可不可以设计一个函数叫repeat(n,f)或repeat(n),它不仅能够重复执行一个任务n遍,还能够像上面的函数一样本身也具备叠加等数的性质?比如repeat(n,repeat(n,repeat(n,...)))。
  2. 在示例中用到的f和x两个函数,它们都具备入参x,入参x能否省略,为什么?
  3. 前文中提到n(f)(x)中,x从来不被执行。因此,在x处传入任何东西都是可以的。这句话是对还是不对?为什么?






© 著作权归作者所有

共有 人打赏支持
ueharaai
粉丝 42
博文 22
码字总数 18134
作品 0
徐汇
技术主管
Python运算符

一、基本概念 1、Python语言支持的运算符类型   算数运算符、比较运算符、赋值运算符、逻辑运算符、位运算符、成员运算符、身份运算符、运算符优先级 2、计算顺序     运算符优先级表决...

bxst
2017/07/13
0
0
Python基础手册9——数字类型

Number(数字) Python的数字由字面值生成或者由算术操作符和内建的算术函数作为结果返回。数字提供了标量贮存和直接访问,它是不可更改类型,也就是说变更数字的值会生成新的对象。Python数...

常大鹏
01/09
0
0
JavaScript基础(三)运算符和数据类型转换

JavaScript运算符 一、运算符和操作数的组合就称为表达式。 二、javascript运算符 (一) 算术运算符 + - * / % var++ ++var var-- --var A. + (1) 用于数值的运算 (2) 用于字符串的连接 *** ...

曾杨
2013/12/26
0
1
五、MySQL函数

函数表示对输入参数值返回一个具有特定关系的值MySQL提供大量丰富的函数在进行数据库管理以及数据的查询和操作时将会经常用到各种函数。通过对数据的处理数据库功能可以变得更加强大更加灵活...

运维菜鸟丶
2017/08/01
0
0
ARM处理器CPSR标志位和条件符之间的关系

本文目的是要理清ARM处理器的CPSR状态标志和ARM指令的条件符之间的关系。 一、CPSR寄存器 ARM V4的CPSR寄存器(和保存它的SPSR寄存器)中的位分配如下图1所示。 图1 程序状态寄存器格式 状态...

LiSteven
2013/08/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

GO 数组相关操作

package mainimport("fmt""math/rand""time")func main() {//数组的几种定义方式var arr1 [3]int = [3]int{1,2,3}var arr2 = [3]int{4,5,6}arr3 := [3]string{"h", "w", ......

汤汤圆圆
30分钟前
1
0
JAVA 中interrupt、interrupted和isInterrupted的区别

首先,我们说明下三个方法的功能 interrupt() 向当前调用者线程发出中断信号 isinterrupted() 查看当前中断信号是true还是false interrupted() 是静态方法,查看返回当前中断信号并将中断信号...

我爱春天的毛毛雨
34分钟前
1
0
Coding and Paper Letter(二十二)

资源整理。 1 Coding: 1.开源项目openeo api。oponEO开发了一个开放的API,以简单统一的方式将R,python和javascript客户端连接到对地观测大数据云平台的后台。 此存储库包含此API,即oponE...

胖胖雕
今天
1
0
RxJS的另外四种实现方式(三)——性能最高的库

接上篇 RxJS的另外四种实现方式(二)——代码最小的库(续) 代码最小的库rx4rx-lite虽然在性能测试中超过了callbag,但和most库较量的时候却落败了,于是我下载了most库,要解开most库性能...

一个灰
今天
5
0
马太效应

马太效应

yizhichao
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部