书签 分享 收藏 举报 版权申诉 / 50
上传文档赚钱

类型函数式程序设计语言.ppt

  • 上传人(卖家):三亚风情
  • 文档编号:3442608
  • 上传时间:2022-08-31
  • 格式:PPT
  • 页数:50
  • 大小:299KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《函数式程序设计语言.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    函数 程序设计语言
    资源描述:

    1、第5章 函数式程序设计语言 过程式程序设计语言由于数据的名值分离,变量的时空特性导致程序难于查错、难于修改 命令式语言天生带来的三个问题只解决了一半 滥用goto已经完全解决 悬挂指针没有完全解决 函数副作用不可能消除 问题是程序状态的易变性(Mutability)和顺序性(Sequencing)Backus在图灵奖的一篇演说程序设计能从冯诺依曼风格下解放出来吗?中极力鼓吹发展与数学连系更密切的函数式程序设计语言5 5.1.1 过程式语言存在的问题过程式语言存在的问题(1 1)易变性难于数学模型易变性难于数学模型 代数中的变量是未知的确定值,而程序设计语言的变量是对存储的抽象 根本解决:能不能

    2、不要程序意义的“变量”只保留数学意义的“变量”?能不能消除函数的副作用?例例:有副作用的函数有副作用的函数 int sf_fun(int x)int sf_fun(int x)static int z=0 static int z=0;/第一次装入赋初值第一次装入赋初值 return x+(z+)return x+(z+);sf_fun(3)=3|4|5|6|7 sf_fun(3)=3|4|5|6|7 /随调用次数而异随调用次数而异,不是数学意义的确定函数。不是数学意义的确定函数。(2)顺序性更难数学模型顺序性更难数学模型 顺序性影响计算结果,例如,前述急求值、正规求值、懒求值同一表达式就会有

    3、不同的结果。有副作用更甚,因而难于为程序建立统一的符号数学理论。应寻求与求值顺序无关的表达方式 理想的改变途径 没有变量,就没有破坏性赋值,也不会有引起副作用的全局量和局部量之分。调用通过引用就没有意义。循环也没有意义,因为只有每次执行循环改变了控制变量的值,循环才能得到不同的结果。那么程序结构只剩下表达式、条件表达式、递归表达式。5.2 演算 演算是符号的逻辑演算系统,它正好只有这三种机制,它就成为函数式程序设计语言的模型 演算是一个符号、逻辑系统,其公式就是符号串并按逻辑规则操纵 Church的理论证明,演算是个完备的系统,可以表示任何计算函数,所以任何可用演算仿真实现的语言也是完备的。演

    4、算使函数概念形式化,是涉及变量、函数、函数组合规则的演算。演算基于最简单的定义函数的思想:一为函数抽象x.E,一为函数应用(x.E)(a)。一切变量、标识符、表达式都是函数或(复合)高阶函数。如x.C(C为常量)是常函数。演算公式举例x x 变量、公式、表达式。(x.(y)x)x.(y)x)函数,体内嵌入应用。(z.(y(z.x)z.(y(z.x)函数,体内嵌入应用,再次嵌入函数。(z.(z y)x)z.(z y)x)应用表达式。x.y.z.(x x.(u v)w)x.y.z.(x x.(u v)w)复杂表达式由于演算中一切语义概念均用表达式表达。为了清晰采用命名替换使之更易读。T=x.y.x

    5、 /逻辑真值F=x.y.y /逻辑假值1=x.y.x y /数12=x.y.x(x y)/数2zerop=n.n(x.F)T /判零函数注:zerop中的F、T可以用表达式展开形式语法形式语法核心的演算没有类型,没有顺序控制等概念,程序和数据没有区分。语法极简单::=|.|()|():=基本函数基本函数 TRUE 和FALSE的表达式 T=x.y.x T=x.y.x F=x.y.y F=x.y.y 整数的表达式:0=x.y.y 1=x.y.x y 2=x.y.x(x y)n=x.y.x(x(x y)n个 基本操作函数 not=z.(zF)T)=z.(zx.y.y)(x.y.x)not=z.(z

    6、F)T)=z.(zx.y.y)(x.y.x)and=a.b.(ab)F)=a.b.(ab)x.y.y)and=a.b.(ab)F)=a.b.(ab)x.y.y)or=a.b.(aT)b)=a.b.(a x.y.x)b)or=a.b.(aT)b)=a.b.(a x.y.x)b)以下是算术操作函数举例:+=+=add=x.y.a.b.(xa)(ya)b)add=x.y.a.b.(xa)(ya)b)*=multiply=x.y.a.(x(ya)=multiply=x.y.a.(x(ya)*=sqr=x.y.(yx)=sqr=x.y.(yx)identity=x.x /identity=x.x /同一

    7、函数同一函数 succ=n.(x.y.nx(x y)/succ=n.(x.y.nx(x y)/后继函数后继函数zerop=n.n(x.F)T zerop=n.n(x.F)T =n.n(z.x.y.y)(x.y.y)/=n.n(z.x.y.y)(x.y.y)/判零判零 函数函数 例:例:3+43+4就写就写add 3 4add 3 4,add 3 add 3返回返回“加加3 3函数函数”应用到应用到4 4上当然就是上当然就是7 7。写全了是:。写全了是:(x.y.a.b.(x a)(y a)b)x.y.a.b.(x a)(y a)b))(p.q.(p(p(p q)(s.t.(s(s(s(s t)

    8、(p.q.(p(p(p q)(s.t.(s(s(s(s t)a.b.(a(a(a(a(a(a(a b)a.b.(a(a(a(a(a(a(a b)归约与范式归约与范式归约将复杂的表达式化成简单形式,归约将复杂的表达式化成简单形式,即按一定的即按一定的规则对符号表达式进行置换。规则对符号表达式进行置换。例例:归约数归约数1 1的后继的后继 (succ 1)=(succ 1)=(nn.(x.y.n x(x y).(x.y.n x(x y)1 1)=(=(x.y.1 x(x y)x.y.1 x(x y)=(x.y.(=(x.y.(pp.q.p q).q.p q)x x(x y)(x y)=(=(x.y

    9、.(q.x q)(x y)x.y.(q.x q)(x y)=(x.y.x(x y)=2 =(x.y.x(x y)=2注:注:succsucc和和1 1都是函数都是函数(1(1是常函数是常函数),第一步是,第一步是nn束定的束定的n n被被1 1置换。置换。展开后,展开后,x x置换置换p p,(xy)(xy)置换置换q q,最后一行不能再置换了,最后一行不能再置换了,它就是范式,它就是范式,语语义为义为2 2。(1 1)归约归约:归约的表达式是一个归约的表达式是一个应用表应用表达式达式(x.M N)x.M N),其左边子表达式是其左边子表达式是函数表函数表达式,右边是任意达式,右边是任意表达式

    10、。表达式。归约以右边的归约以右边的表达式置换函数体表达式置换函数体M M中中指明的那个形参变量。指明的那个形参变量。形式地,我们用形式地,我们用 N/X,MN/X,M表示对(表示对(x.M Nx.M N)的的置换置换(规则(规则略)。略)。关键的问题是注意函数体中要置换的变量是否关键的问题是注意函数体中要置换的变量是否自由出现,如:自由出现,如:(x.x(x.(xy)(zz)x.x(x.(xy)(zz)=(zz)(x.(zz)y)=(zz)(x.(zz)y)/错误,第二错误,第二x x个非自由出现。个非自由出现。=(=(zz)(x.(xy)/zz)(x.(xy)/正确例例5 5-5-5 高层表

    11、示的高层表示的归约归约(n.add n n)3n.add n n)3 =add 3 3 /3 =add 3 3 /3置换置换n n后取消后取消nn =6 =6(f.x.f(f x)succ 7(f.x.f(f x)succ 7 =x.succ(succ x)7 =x.succ(succ x)7 =succ(succ 7)=succ(succ 7)=succ(8)=9 =succ(8)=9注注:addadd,3 3,succ succ,7 7,9 9是为了清晰没进是为了清晰没进 一步展开为一步展开为表达式。表达式。但但归约有时并不能简化归约有时并不能简化,如如:(x.xx)(x.xx)x.xx)

    12、(x.xx),归约后仍是原公式,归约后仍是原公式,这种这种表达式称为不可归约的。表达式称为不可归约的。对应为程序设对应为程序设计语言中的无限递归。计语言中的无限递归。(2)(2)归约是消除一层约束的归约归约是消除一层约束的归约:x.Fx=Fx.Fx=F (3)(3)换名换名:归约中如发生改变束定性质,归约中如发生改变束定性质,则允则允许换名许换名(后跟的变量名后跟的变量名),以保证原有束定以保证原有束定关系。关系。例如:例如:(x.(y.x)(z y)/(zy)x.(y.x)(z y)/(zy)中中y y是自由变量是自由变量 =y.(zy)/y.(zy)/此时此时(zy)zy)中中y y被束定

    13、了,被束定了,错误!错误!=(=(x.(w.x)(zy)/x.(w.x)(zy)/因因(y.x)y.x)中函数体中函数体 无无y y,可换名可换名 =w.(zy)/w.(zy)/正确!正确!(4)(4)归约约定归约约定 顺序顺序:每次归约只要找到可归约的子公式即可归每次归约只要找到可归约的子公式即可归约,约,演算没有规定顺序。演算没有规定顺序。范式范式:符号归约当施行(除符号归约当施行(除规则外)所有变换规则外)所有变换规则后没有新形式出现,则这种规则后没有新形式出现,则这种表达式叫范式。表达式叫范式。解释解释:范式即范式即演算的语义解释,演算的语义解释,形如形如 x xx x,(y(x.z)

    14、(y(x.z)就只能解释为数据了就只能解释为数据了。上述基本函数均为范式,上述基本函数均为范式,在它的上面取上有意义在它的上面取上有意义的名字可以构成上一层的函数,的名字可以构成上一层的函数,如:如:pred=n.(subtract n 1)pred=n.(subtract n 1)(5)综合规约例题综合规约例题:以以演算规约演算规约3 3*2 2 3 3*2=2=*(3)(2)(3)(2)=x.y.(y x)(3)(2)x.y.(y x)(3)(2)(y.(y 3)(2)(y.(y 3)(2)(2)3)(2)3)=(f.c.f(f c)(3)(f.c.f(f c)(3)c.(3(3 c)c.

    15、(3(3 c)=c.(f.c.(f(f(f(c)(3 c)c.(f.c.(f(f(f(c)(3 c)/有有c c不能置换不能置换c c c.(f.z.(f(f(f(z)(3 c)c.(f.z.(f(f(f(z)(3 c)c.(z.(3 c)(3 c)(3 c)(z)c.(z.(3 c)(3 c)(3 c)(z)/再展再展3 3=c.z.(c.z.(f.c.(f(f(f(c)c)(3c)(3c)(z)f.c.(f(f(f(c)c)(3c)(3c)(z)c.z.(c.z.(f.w.(f(f(f(w)c)(3c)(3c)(z)f.w.(f(f(f(w)c)(3c)(3c)(z)c.z.(w.(c(c

    16、(c(w)(3c)(3c)(z)c.z.(w.(c(c(c(w)(3c)(3c)(z)/同理展开第二个同理展开第二个c,c,第三个第三个c c=c.z.(w.(c(c(c(w)(c.z.(w.(c(c(c(w)(p.(c(c(c(p)(p.(c(c(c(p)(q.(c(c(c(q)(z)q.(c(c(c(q)(z)c.z.(w.(c(c(c(w)(c.z.(w.(c(c(c(w)(p.(c(c(c(p)(c(c(c(z)p.(c(c(c(p)(c(c(c(z)c.z.(w.(c(c(c(w)(c.z.(w.(c(c(c(w)(c(c(c(c(c(c(z)(c(c(c(c(c(c(z)c.z.(

    17、c(c(c(c(c(c(c(c(c(z)=9 c.z.(c(c(c(c(c(c(c(c(c(z)=9增强增强演算演算只用最底层只用最底层演算是极其复杂的。用高层命名函数,语义演算是极其复杂的。用高层命名函数,语义清晰。不仅如此,保留一些常见关键字,语义更清晰。例清晰。不仅如此,保留一些常见关键字,语义更清晰。例如,我们可以定义一个如,我们可以定义一个if_then_elseif_then_else为名的函数:为名的函数:if_then_else=p.m.n.p m nif_then_else=p.m.n.p m n,当当p p为为 真真 时,时,执执行行m m否则为否则为n n。我们先验证其真

    18、伪。我们先验证其真伪。例例:当条件表达式为真时当条件表达式为真时if_then_elseif_then_else函数的归约函数的归约(if_then_else)T M Nif_then_else)T M N=(p.m.n.p m n)T M N=(p.m.n.p m n)T M N=(m.n.(T m n)M N=(m.n.(T m n)M N=(m.n.(x.y.x)m n)M N=(m.n.(x.y.x)m n)M N=(m.n.(y.m)n)M N=(m.n.(y.m)n)M N=(m.n.m)M N=(m.n.m)M N=(n.M)N=(n.M)N=M=M ifif表达式表达式 可保留

    19、显式if-then-else形式:(if_then_else)E1 E2 E3=if E1 then E2 else E3 其中E1,E2,E3为表达式。Let/whereLet/where表达式表达式 如果有高阶函数:如果有高阶函数:(n.multiply n(succ n)(add i 2)n.multiply n(succ n)(add i 2)=multiply(add i 2)(succ(add i 2)multiply(add i 2)(succ(add i 2)/n n 和和 add i 2add i 2置换变元得置换变元得=multiply n(succ n)/let n=ad

    20、d i 2 in multiply n(succ n)/let n=add i 2 in let a=b in E (a.E)b E where a=b let a=b in E (a.E)b E where a=b (f.E2)(x.E1)=let f=x.E1 in E2f.E2)(x.E1)=let f=x.E1 in E2 =let f x=E1 in E2 =let f x=E1 in E2其中形如其中形如f=x.E1f=x.E1的的x.x.可移向左边为可移向左边为f x=E1 f x=E1。如如:sqr=n.multiply n n /sqr=n.multiply n n /整个是

    21、整个是函数表达式函数表达式 sqr n=multiply n n /sqr n=multiply n n /两应用表达式也相等两应用表达式也相等 letlet表达式在表达式在ML.LISPML.LISP中直接采用,中直接采用,MirandaMiranda用用wherewhere关键字使程序更好读,关键字使程序更好读,letlet直到直到E E完结构成一个程序块。完结构成一个程序块。MirandaMiranda只不过把只不过把wherewhere块放在块放在E E之后之后.元组表达式元组表达式一般情况下一般情况下n n元组是元组是p=(xp=(x1 1,x,x2 2,x xn n),),建立在建

    22、立在p p上上函数有:函数有:let f(xlet f(x1 1,x,x2 2,x xn n)=E1 in E2)=E1 in E2 let fp=E1 in let fp=E1 in let x let x1 1=first p in=first p in let x let x2 2=second p in=second p in .let x let xn n=n_th p in E2=n_th p in E25 5.3.3 函数式语言怎样克服命令函数式语言怎样克服命令式语言的缺点式语言的缺点 5 5.3.1.3.1 消除赋值消除赋值赋值语句在过程语言中起什么作用。在函数式语言中取消会有

    23、什么问题:1 存储计算子表达式的中间结果。2 条件语句的重要组成。3 用于循环控制变量。4 处理复杂数据结构(增删改某个成分)。解决办法 1:保留全局量、局部量保留全局量、局部量(符号名符号名)以及参数名以及参数名。22:用条件表达式代替条件语句,其返回值通过用条件表达式代替条件语句,其返回值通过 参数束定或参数束定或wherewhere子句束定于名字子句束定于名字33:函数式语言都要定义表数据结构,函数式语言都要定义表数据结构,因为归约因为归约 和递归计算在表上很方便。和递归计算在表上很方便。对整个表操作实对整个表操作实 则是隐式迭代。则是隐式迭代。不用循环控制变量。不用循环控制变量。对于对

    24、于 顺序值也都用表写个映射函数即可隐式迭代。顺序值也都用表写个映射函数即可隐式迭代。部分达到作用部分达到作用33,其它显式循环要用递归。其它显式循环要用递归。4:4:禁止赋值意味着数据结构一旦创建不得修禁止赋值意味着数据结构一旦创建不得修改改,故采用如下函数式语言结构数据修改方式故采用如下函数式语言结构数据修改方式ABCEHGDFBCAFJI5 5.3.2.3.2 以递归代替以递归代替while_dowhile_do 组织仿真的要点是把递归函数体写入条件表达组织仿真的要点是把递归函数体写入条件表达式。式。循环终止条件是条件测试部分,循环终止条件是条件测试部分,函数如函数如有返回值放在有返回值放

    25、在thenthen部分,部分,递归函数体放在递归函数体放在elseelse部分,部分,如果不需返回值则取消一部分如果不需返回值则取消一部分(else)else)。5 5.3.3.3.3 消除顺序消除顺序一旦语义相关无法传递数据,一旦语义相关无法传递数据,非得写成嵌套函非得写成嵌套函数不可数不可(返回值自动束定到外套函数的变元上返回值自动束定到外套函数的变元上)例例:pascalpascal实现:实现:c c:=a+b=a+b;s s:=sin(c=sin(c*c)c);。write(a write(a,b b,c c,s)s);/上面计算不进行是无法打印/的逻辑上要有顺序。LISP LISP

    26、实现实现:(print(let(c(+a b)print(let(c(+a b)let(s(sin(let(s(sin(*c c)c c)list a b c s)list a b c s)/仍有顺序但在一个 /表达式内。自左至右处理即隐式顺序。MirandaMiranda实现:实现:Answere a b=(a b c s)Answere a b=(a b c s)where where s=sin(c s=sin(c*c)c)c=a+b c=a+b /多么清晰,全然没有顺序5 5.3.4.3.4用嵌套代替语义相关的顺用嵌套代替语义相关的顺序 用懒求值代替顺序用懒求值代替顺序 利用卫式进一步

    27、消除顺序性利用卫式进一步消除顺序性MirandaMiranda的卫式表达式的卫式表达式 gcd a b=gcd(a-b)bgcd a b=gcd(a-b)b,ab ab =gcd a(b-a)=gcd a(b-a),ab a max2 2 max1 max2 2 =max2 =max2,max2 max1 3 max2 max1 3 =max1=max1,otherwise otherwise where where max1=(max_tree n1)4 max1=(max_tree n1)4 max2=(max_tree n2)5 max2=(max_tree n2)5如有应用:如有应用:

    28、(max_tree leaf1)max_tree leaf1)/结果值为结果值为3 3,leaf1leaf1用上例用上例(max_tree tree1)max_tree tree1)/结果值为结果值为4949,tree1tree1用上例用上例 表表(list)list)MirandaMiranda表的表示法表的表示法 /空表空表1.1.nn /1 /1到到n,n,域表示域表示odd_number=1odd_number=1,3 3,.100.100 /1 /1到到100100内奇数表,头两项及最后项必写内奇数表,头两项及最后项必写eleven_up=11.eleven_up=11./10 /1

    29、0以上,以上,无限表表示无限表表示evens=10evens=10,12.10012.100 /10 /10以上偶数表至以上偶数表至100100,头两项及最后项必写,头两项及最后项必写evens_up=12evens_up=12,14.14./10 /10以上偶数无限表,以上偶数无限表,week _days=week _days=“MonMon”,“TueTue”,“WedWed”,“ThurThur”,“FriFri”/五个串值的表五个串值的表5 5.4.2.4.2 内定义操作内定义操作MirandaMiranda定义了常规的算术运算符定义了常规的算术运算符(+(+、-、*、/、divdiv

    30、、mod)mod)并按中缀表示使用。故内定义了一些并按中缀表示使用。故内定义了一些有用的表操作:有用的表操作:L1+L2 /L1+L2 /表表L2L2并接到表并接到表L1L1的末尾的末尾 item:List /item:List /将项将项itemitem加到表加到表ListList的头前的头前 List List!n /n /从表从表ListList中选取第中选取第n n项项 L1-L2 /L1-L2 /从表从表L1L1中剔出中剔出L2L2的值的值#List /List /返回表返回表ListList的项的项(基基)数数5 5.4.3.4.3 定义函数定义函数MirandaMiranda把函

    31、数定义叫方程把函数定义叫方程(equation)equation)。例例:斐波那契数的函数定义,斐波那契数的函数定义,用卫式表达式实现递归用卫式表达式实现递归Fibonacci n=1Fibonacci n=1,n=0 n=0 =1 =1,n=1 n=1 =Fibonacci(n-1)+Fibonacci(n-2)n1 =Fibonacci(n-1)+Fibonacci(n-2)n1 卫式表达式的值集应复盖所有的可能,卫式表达式的值集应复盖所有的可能,否则用否则用otherwiseotherwise。例例:利用利用wherewhere解二次方程解二次方程quadroot a b c=error

    32、 quadroot a b c=error“complex rootscomplex roots”,delta 0delta 0 delta 0 where where delta=b delta=b*b-4b-4*a a*c c radix=sqrt delta radix=sqrt delta term1=-b/(2 term1=-b/(2*a)a)term2=radix/(2 term2=radix/(2*a)a)MirandaMiranda完全按完全按演算模型,每个函数都是一元运算,当演算模型,每个函数都是一元运算,当有多个变元时,有多个变元时,函数名也是第一类对象,函数名也是第一类对

    33、象,它逐一应用到它逐一应用到各个参数,各个参数,中间返回函数可以任意取名,中间返回函数可以任意取名,这种中间函数这种中间函数称称CurryCurry函数函数。例例:直角三角形求斜边长函数直角三角形求斜边长函数 hypotenuse a b=sqrt(a hypotenuse a b=sqrt(a*a+b a+b*b)b)调用时调用时 hypotenuse 3 4 /=5hypotenuse 3 4 /=5也可写作:也可写作:(hypotenuse 3)4 hypotenuse 3)4 f 4 f 4 Miranda Miranda则写作为:则写作为:f 4 where f=hypotenuse

    34、 3 f 4 where f=hypotenuse 3 /f=sqrt(9+b /f=sqrt(9+b*b)b)即即 Curry Curry 函数。函数。例例:MirandaMiranda用变阶函数实现类型参数化。用变阶函数实现类型参数化。type row_type=array0.9 of Integer;type row_type=array0.9 of Integer;function Reduce(functionf(x:Integer,y:Integer):Integer;function Reduce(functionf(x:Integer,y:Integer):Integer;ar

    35、:row_type):Integer;/ar:row_type):Integer;/函数函数f f是参数化的。是参数化的。var sum,k:Integer;var sum,k:Integer;beginbegin sum:=ar0;sum:=ar0;for k=1 to 9 do for k=1 to 9 do sum:=f(sum,ark);sum:=f(sum,ark);reduce:=sum reduce:=sumend;end;function MyOp(s:Integer,y:Integer):Integer;/function MyOp(s:Integer,y:Integer):

    36、Integer;/此处此处定义一实例函数。定义一实例函数。beginbegin MyOp:=abs(x)+abs(y)MyOp:=abs(x)+abs(y)end;end;function MySum(ar:row_type):Integer;function MySum(ar:row_type):Integer;begin MySum:=Reduce(MyOp,ar)end;begin MySum:=Reduce(MyOp,ar)end;上上程序仅将程序仅将 ReduceReduce函数操作参数化。数组元素类型、长度还是固函数操作参数化。数组元素类型、长度还是固定的。定的。MirandaMi

    37、randa都可以,它设都可以,它设3 3个参数:操作、表、单位元。单位个参数:操作、表、单位元。单位元的值可用于归约过程的初始化值,也是空表时的返回值:元的值可用于归约过程的初始化值,也是空表时的返回值:reduce f n=n 1reduce f n=n 1reduce f(a:x)n=f a(reduce x n)2reduce f(a:x)n=f a(reduce x n)2为了理解上不引起岐意,写明为了理解上不引起岐意,写明reducereduce的类型:的类型:reduce:(numreduce:(numnumnumnum)/num)/第一变元第一变元f f是函数类型(有是函数类型(

    38、有 括号)括号),它是二元算子它是二元算子 num /num /返回值是表,表元素是返回值是表,表元素是numnum类类型型 num /num /若空表映射为数,类型是若空表映射为数,类型是num.num.num /num /最后映射返回值是最后映射返回值是numnum类型。类型。22行中(行中(a:xa:x)是表头是表头a a和表尾和表尾x x,右边函数体是表尾归约后与表右边函数体是表尾归约后与表头归约。头归约。11行指明空表规约行指明空表规约 n n 次是单位元的次是单位元的 n n 次复合。次复合。5 5.4.4.4.4 表闭包表闭包表闭包是一个任意复杂结构的表闭包是一个任意复杂结构的(

    39、无限无限)表。其语法是:表。其语法是::=:=|:=:=;|:=:=:=:=:=:=表闭包示例表闭包示例:ZF ZF 表达式表达式 解释解释 n n*2|n22|n2,4 4,6 6,8 8,10 10 44,8 8,1212,1616,2020 1 1nn*n|n 1n|n 1,2 2,.11,4 4,9 9,.2 2x+y|x 1.3x+y|x 1.3;y3 y3,7 7 44,5 5,6 6,8 8,9 9,1010 3 3xx*y|x 1.3y|x 1.3;y1.3 y1.3;x=yx=y11,2 2,4 4,3 3,6 6,99 4 411行只有一个生成器,行只有一个生成器,表值表值

    40、2 2,4 4,6 6,8 8,1010束定于束定于n n得出得出2 2倍表。倍表。22行是无限表也只有一产生器,行是无限表也只有一产生器,33行行44行有两个产生器,行有两个产生器,4 4行还有一过滤器,行还有一过滤器,否则要对称出否则要对称出9 9个数。个数。例例:用用MirandaMiranda编写快速分类编写快速分类 sort =1sort =1sort(pivotsort(pivot:rest)=sort y|y restrest)=sort y|y rest;y=pivot 2 ypivot 4 ypivot 4 1 1行定义函数行定义函数sortsort的变元是空表它返回一空表的

    41、变元是空表它返回一空表(调用同一函调用同一函数数),一般定义递归它都有一般定义递归它都有11行。行。它同时指出它同时指出sortsort是表变元。是表变元。22行的圆括号不是表,行的圆括号不是表,而是说明变元一个表,而是说明变元一个表,它由元组它由元组pivotpivot和和restrest组成,即表头、表尾。组成,即表头、表尾。以局部的名字给出了与之结合的实参以局部的名字给出了与之结合的实参表表头、表尾。表表头、表尾。5 5.4.5.4.5 无限表无限表 可以把无限表看作两部分:有限的头部,它放已经算好了的值,和一个无限的尾,它由生成新表尾的代码组成。这相当于一个函数,也采用懒求值,即不到表

    42、不够时不计算它。5 5.5.5 问题与讨论问题与讨论(1)(1)模拟状态不易模拟状态不易(2)(2)效率还是问题效率还是问题 从过去比顺序的命令式语言慢从过去比顺序的命令式语言慢200-1000200-1000倍到近来的倍到近来的3-53-5倍,倍,其原因是:其原因是:函数是第一类对象,函数是第一类对象,局部于它的数据一般要在堆局部于它的数据一般要在堆(heap)heap)上分上分配,配,为了避免悬挂引用,为了避免悬挂引用,要有自动重配的检查。要有自动重配的检查。无类型无类型(如如LISP)LISP)要在运行中检查类型,即使是强类型的要在运行中检查类型,即使是强类型的(如如MLML,Miran

    43、da)Miranda)减少了类型动态检查,减少了类型动态检查,但函数式语言天然匹配选择但函数式语言天然匹配选择模式的途径也是运行低效原因。模式的途径也是运行低效原因。懒求值开销大懒求值开销大中间复合值一多费时费空间。中间复合值一多费时费空间。无限表动态生成,无限表动态生成,计算一次增长一个元素!计算一次增长一个元素!效率也很低。效率也很低。(3)(3)并发性并发性函数式语言被认为是非常适用于处理并发性问题的函数式语言被认为是非常适用于处理并发性问题的工具,工具,共享值不需加特殊保护,共享值不需加特殊保护,因为他们不会被因为他们不会被更新更新、并行进程之间不会互相干扰。并行进程之间不会互相干扰。

    44、还有一些困难问题要解决。还有一些困难问题要解决。在将表达式求值分配给在将表达式求值分配给不同的处理器这一点上就有隐藏的额外开销:不同的处理器这一点上就有隐藏的额外开销:用于用于求表达式值的数据必须从一个处理器传到另一个处求表达式值的数据必须从一个处理器传到另一个处理器,理器,而表达式的计算结果还得被传回来。而表达式的计算结果还得被传回来。寻找解决这个问题的先进技术是一个热门的研究课寻找解决这个问题的先进技术是一个热门的研究课题。题。Haskell 语言 Haskell是一种标准化的,通用纯函数式编程语言,有非限定性语义和强静态类型。它的命名源自美国逻辑学家Haskell Brooks Curr

    45、y,他在数学逻辑方面的工作使得函数式编程语言有了广泛的基础。在Haskell中,函数是一等公民。作为函数式编程语言,主要控制结构是函数。Haskell语言是1990年在编程语言Miranda的基础上标准化的,并且以演算(Lambda-Calculus)为基础发展而来。具有“证明即程序、结论公式即程序类型”的特征。这也是Haskell语言以希腊字母(Lambda)作为自己标志的原因。Scheme 语言 Scheme 语言是 Lisp 的一个现代变种、方言,诞生于1975年,由 MIT 的 Gerald J.Sussman and Guy L.Steele Jr.完成。与其他lisp不同的是,sc

    46、heme是可以编译成机器码的。Scheme语言的规范很短,总共只有50页,甚至连Common Lisp 规范的索引的长度都不到,但是却被称为是现代编程语言王国的皇后。它与以前和以后的 Lisp 实现版本都存在一些差异,但是却易学易用。Clojure 语言 Clojure 是一种运行在 Java 平台上的 Lisp 方言,它的出现彻底颠覆了我们在Java虚拟机上并发编程的思考方式改变了这一现状。如今,在任何具备 Java 虚拟机的地方,您都可以利用 Lisp 的强大功能 作为Lisp方言,Clojure或许拥有最灵活的编程模型,因此绝不缺乏号召力。与其他Lisp方言不同的是,它不会带那么多括号,

    47、还有众多Java库和在各平台上的广泛部署作为坚强后盾 Scala 语言 Scala是一种函数式面向对象语言,它融汇了许多前所未有的特性,而同时又运行于JVM之上。随着开发者对Scala的兴趣日增,以及越来越多的工具支持,无疑Scala语言将成为你手上一件必不可少的工具。Scala为Java系统引入了强大的函数式思想,同时也并未丢弃面向对象编程。回顾历史,我发现C+和Scala有着惊人的相似之处,因为从过程式编程过渡到面向对象编程期间,C+同样起到了举足轻重的作用。当你真正融入Scala社区之后,你就会明白,为什么对于函数式语言程序员来说,Scala是异端邪说,而对于Java开发者来说,Scala是天降福音。

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:函数式程序设计语言.ppt
    链接地址:https://www.163wenku.com/p-3442608.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库