Object.send(:remove_const,'TRUE')
Object.send(:remove_const,'FALSE') def to_integer(pro)
pro[-> n { n + 1 }][0]
end def to_boolean(pro)
pro[true][false]
end def to_array(l, count = nil)
array = []
until to_boolean(IS_EMPTY[l]) || count == 0
array.push FIRST[l]
l = REST[l]
count = count - 1 unless count.nil?
end
array
end def array_map_to_integer(my_list, count = nil)
to_array(my_list, count).map{ |p| to_integer(p) }
end def to_char(c)
to_integer(c).chr
end def to_string(s)
to_array(s).map{ |c| to_char(c) }.join
end def puts_strings(strs)
to_array(strs).each do |p|
puts to_string(p)
end
nil
end ZERO = -> p { -> x { x } }
ONE = -> p { -> x { p[x] } }
TWO = -> p { -> x { p[p[x]] } }
THREE = -> p { -> x { p[p[p[x]]] } } FIVE = -> p { -> x { p[p[p[p[p[x]]]]] } } FIFTEEN = -> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]] } }
HUNDRED = -> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] } } TRUE = -> x { -> y { x } }
FALSE = -> x { -> y { y } } IF = -> b { b } IS_ZERO = -> n { n[-> x { FALSE }][TRUE] } PAIR = -> x { -> y { -> f { f[x][y] } } }
LEFT = -> p { p[-> x { -> y { x } }] }
RIGHT = -> p { p[-> x { -> y { y } }] } INC = -> n { -> p { -> x { p[n[p][x]] } } } SLIDE = -> p { PAIR[RIGHT[p]][INC[RIGHT[p]]] }
DEC = -> n { LEFT[n[SLIDE][PAIR[ZERO][ZERO]]] } ADD = -> m { -> n { n[INC][m] } }
SUB = -> m { -> n { n[DEC][m] } }
MUL = -> m { -> n { n[ADD[m]][ZERO] } }
POW = -> m { -> n { n[MUL[m]][ONE] } } IS_LESS_OR_EQUAL =
-> m { -> n { IS_ZERO[SUB[m][n]] } } Z = -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }
MOD = Z[-> f { -> m { -> n {
IF[IS_LESS_OR_EQUAL[n][m]][
-> x {
f[SUB[m][n]][n][x]
}
][
m
]
} } }] DIV = Z[-> f { -> m { -> n {
IF[IS_LESS_OR_EQUAL[n][m]][
-> x {
INC[f[SUB[m][n]][n]][x]
}
][
ZERO
]
} } } ] EMPTY = PAIR[TRUE][TRUE]
UNSHIFT = -> l { -> x { PAIR[FALSE][PAIR[x][l]] } }
IS_EMPTY= LEFT
FIRST = -> l { LEFT[RIGHT[l]] }
REST = -> l { RIGHT[RIGHT[l]] } PUSH = -> l { -> x {
FOLD[l][UNSHIFT[EMPTY][x]][UNSHIFT]
} } RANGE = Z[-> f {
-> m { -> n {
IF[IS_LESS_OR_EQUAL[m][n]][
-> x {
UNSHIFT[f[INC[m]][n]][m][x]
}
][
EMPTY
]
} }
}]
FOLD = Z[-> f {
-> l { -> x { -> g {
IF[IS_EMPTY[l]][
x
][
-> y {
g[f[REST[l]][x][g]][FIRST[l]][y]
}
]
} } }
}] MAP = -> k { -> f {
FOLD[k][EMPTY][
-> l { -> x { UNSHIFT[l][f[x]] } }
]
} } TEN = MUL[TWO][FIVE]
ASC_48 = MUL[MUL[THREE][INC[THREE]]][INC[THREE]]
ASC_65 = ADD[MUL[ADD[FIVE][ONE]][TEN]][FIVE]
CHAR_B = INC[ASC_65]
CHAR_F = ADD[ASC_65][FIVE]
CHAR_I = ADD[CHAR_F][THREE]
CHAR_U = ADD[CHAR_I][MUL[THREE][INC[THREE]]]
CHAR_Z = ADD[CHAR_U][FIVE] FIZZ = UNSHIFT[UNSHIFT[UNSHIFT[UNSHIFT[EMPTY][CHAR_Z]][CHAR_Z]][CHAR_I]][CHAR_F]
BUZZ = UNSHIFT[UNSHIFT[UNSHIFT[UNSHIFT[EMPTY][CHAR_Z]][CHAR_Z]][CHAR_U]][CHAR_B]
FIZZBUZZ= UNSHIFT[UNSHIFT[UNSHIFT[UNSHIFT[BUZZ][CHAR_Z]][CHAR_Z]][CHAR_I]][CHAR_F] TO_DIGITS=
Z[-> f { -> n { PUSH[
IF[IS_LESS_OR_EQUAL[n][DEC[TEN]]][
EMPTY
][
-> x {
f[DIV[n][TEN]][x]
}
]
][ADD[MOD[n][TEN]][ASC_48]] } } ] SOLUTION=
MAP[RANGE[ONE][HUNDRED]][-> n {
IF[IS_ZERO[MOD[n][FIFTEEN]]][
FIZZBUZZ
][IF[IS_ZERO[MOD[n][THREE]]][
FIZZ
][IF[IS_ZERO[MOD[n][FIVE]]][
BUZZ
][
TO_DIGITS[n]
]]]
} ] ZEROS = Z[-> f { UNSHIFT[f][ZERO] }]
UPWARDS_OF = Z[-> f { -> n { UNSHIFT[-> x { f[INC[n]][x] }][n] } }]
MULTIPLES_OF =
-> m {
Z[-> f {
-> n { UNSHIFT[-> x { f[ADD[m][n]][x] }][n] }
}][m]
}
MULTIPLY_STREAMS =
Z[-> f {
-> k { -> l {
UNSHIFT[-> x { f[REST[k]][REST[l]][x] }][MUL[FIRST[k]][FIRST[l]]]
} }
}]

在λ演算中,每个表达式都代表一个函数,这个函数有一个参数,并且返回一个值。不论是参数和返回值,也都是一个单参的函数。可以这么说,λ演算中,只有一种“类型”,那就是这种单参函数。

在lambda演算中有许多方式都可以定义自然数,但最常见的还是邱奇数。

ZERO    = -> p { -> x {       x    } }
ONE = -> p { -> x { p[x] } }
TWO = -> p { -> x { p[p[x]] } }
THREE = -> p { -> x { p[p[p[x]]] } } FIVE = -> p { -> x { p[p[p[p[p[x]]]]] } } FIFTEEN = -> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]] } }
HUNDRED = -> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] } }

以此类推。直观地说,lambda演算中的数字n就是一个把函数f作为参数并以f的n次幂为返回值的函数。换句话说,邱奇整数是一个高阶函数 -- 以单一参数函数f为参数,返回另一个单一参数的函数。

习惯上,下述两个定义(称为邱奇布尔值)被用作TRUE和FALSE这样的布尔值:

TRUE    = -> x { -> y { x } }
FALSE = -> x { -> y { y } }

“谓词”是指返回布尔值的函数。最基本的一个谓词是ISZERO,当且仅当其参数为零时返回真,否则返回假:

IS_ZERO = -> n { n[-> x { FALSE }][TRUE] }

运用谓词与上述TRUE和FALSE的定义,使得"if-then-else"这类语句很容易用lambda演算写出。

有序对(2-元组)数据类型可以用TRUE、FALSE和IF来定义。

PAIR    = -> x { -> y { -> f { f[x][y] } } }
LEFT = -> p { p[-> x { -> y { x } }] }
RIGHT = -> p { p[-> x { -> y { y } }] }

链表数据类型可以定义为,要么是为空列表保留的值(e.g.FALSE),要么是CONS一个元素和一个更小的列表。

EMPTY   = PAIR[TRUE][TRUE]
UNSHIFT = -> l { -> x { PAIR[FALSE][PAIR[x][l]] } }
IS_EMPTY= LEFT
FIRST = -> l { LEFT[RIGHT[l]] }
REST = -> l { RIGHT[RIGHT[l]] }

递归是使用函数自身的函数定义;在表面上,lambda演算不允许这样。但是这种印象是误解。

使用Y组合子和Z组合子实现可以递归:

Z       = -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }

从lambda到函数式编程的更多相关文章

  1. java8 array、list操作 汇【4】)- Java8 Lambda表达式 函数式编程

    int tmp1 = 1; //包围类的成员变量 static int tmp2 = 2; //包围类的静态成员变量 //https://blog.csdn.net/chengwangbaiko/ar ...

  2. python 函数对象(函数式编程 lambda、map、filter、reduce)、闭包(closure)

    1.函数对象 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函 ...

  3. Python函数式编程:Lambda表达式

    首先我们要明白在编程语言中,表达式和语句的区别. 表达式是一个由变量.常量.有返回值的函数加运算符组成的一个式子,该式子是有返回值的 ,如  a + 1 就是个表达式, 单独的一个常量.变量 或函数调 ...

  4. C# 函数式编程 —— 使用 Lambda 表达式编写递归函数

    最近看了赵姐夫的这篇博客http://blog.zhaojie.me/2009/08/recursive-lambda-expressions.html,主要讲的是如何使用 Lambda 编写递归函数 ...

  5. Java 中的函数式编程(Functional Programming):Lambda 初识

    Java 8 发布带来的一个主要特性就是对函数式编程的支持. 而 Lambda 表达式就是一个新的并且很重要的一个概念. 它提供了一个简单并且很简洁的编码方式. 首先从几个简单的 Lambda 表达式 ...

  6. 函数式编程--为什么会出现lambda表达式?

    java一直处在发张和演化的过程中,其中有2个版本从根本上改变了代码的编写方式.第一个就是JDK5之后增加的泛型,还有一个就是现在介绍的函数式编程,lambda表达式. lambda表达式是java8 ...

  7. Java函数式编程和lambda表达式

    为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论.函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做.说白了,函数式编程是基于 ...

  8. [学习] 从 函数式编程 到 lambda演算 到 函数的本质 到 组合子逻辑

    函数式编程 阮一峰 <函数式编程初探>,阮一峰是<黑客与画家>的译者. wiki <函数编程语言> 一本好书,<计算机程序的构造与解释>有讲到schem ...

  9. Java8函数式编程和lambda表达式

    文章目录函数式编程JDK8接口新特性函数接口方法引用函数式编程函数式编程更多时候是一种编程的思维方式,是一种方法论.函数式与命令式编程区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉 ...

随机推荐

  1. pollard_rho和Miller_Rabin

    Miller_Rabin就是以概论大小来判断素数 可以判断2^63范围的数 pollard_rho推荐两个很好的博客来理解:整数分解费马方法以及Pollard rho和[ZZ]Pollard Rho算 ...

  2. uvalive 3890 Most Distant Point from the Sea

    题意:求一个凸多边形中一点到边的最大距离. 思路:转换成在多边形内部,到每边距离为d的直线所围成的内多边形是否存在.也就是,二分距离+半平面交. #include<cstdio> #inc ...

  3. MultiByteToWideChar和WideCharToMultiByte用法详解

    今天写ini文件的时候发现的问题: TCHAR temp[]; //strcpy_s(temp, request.newVersion); MultiByteToWideChar(CP_ACP, , ...

  4. FFmpeg YUV视频序列编码为视频

    上一篇已经写了如何配置好开发环境,这次就先小试牛刀,来个视频的编码.搞视频处理的朋友肯定比较熟悉YUV视频序列,很多测试库提供的视频数据都是YUV视频序列,我们这里就用用YUV视频序列来做视频.关于Y ...

  5. ubuntu源码安装R语言

    下载后解压完,进入开始配置: ./configure --enable-R-shlib 报错: configure: error: con--with-readline=yes (default) a ...

  6. javascript操作注册表

    try{                     var shell = new ActiveXObject("WScript.Shell"); //读注册表值var  key1  ...

  7. openstack系列阅读目录

    一 keystone系列 keystone基础 网关协议cgi,fastcgi,wsgi,uwsgi keystone源码分析 keystone部署及使用 keystone客户端工作介绍 二 glan ...

  8. Spring + iBatis 的多库横向切分简易解决思路

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  9. C++ “读取位置 0x****** 时发生访问冲突”的可能原因

    转自:http://shansun123.iteye.com/blog/680066 这种错误的意思一般是指访问了不属于自己的内存空间,出现这种错误有几种原因: 1.给一个数组分配了比较小的内存空间, ...

  10. cocos2d 中加入显示文字的三种方式(CCLabelTTF 、CCLabelBMFont 和CCLabelAtlas)

    在 cocos2d 中有三个类能够在层或精灵中加入文字: CCLabelTTF CCLabelBMFont CCLabelAtlas      CCLabelTTF CCLabelTTF 每次调用 s ...