第一章 什么是函数式编程

it2024-12-26  14

第一章 什么是函数式编程

一.前言

函数式编程:使用纯函数来构造程序。 (1)纯函数是没有副作用的函数。 (2)副作用是指,函数执行过后,不仅有返回值,与此同时,还进行了其他操作:     (a) 修改了其他变量的值     (b) 设置了对象的属性     (c) 抛出了一个异常,或以一个错误终止     (d) 打印到终端,或获取用户键盘输入     (e) 读取或写入一个文件纯函数的优势 (1)纯函数是模块化的,容易被测试,复用,并行化,泛华,推导。因此纯函数降低了bug出生的概率 (2)纯函数限制了怎样写程序,而非限制表达什么样的程序。就是说,纯函数依然能进行IO操作,循环改变变量等

二. 函数式程序对副作用的改造

第一个程序

class Cafe{ def buyCoffee(cc:CreditCard) : Coffee = { val cup = new Coffee() cc.charge(cup.price) // 这段代码出现副作用: cup } }

(1)函数只是为了返回一个Coffee对象,而在此过程中,却涉及到了CreditCard对象的更改。因此产生副作用,这个副作用使得代码难以测试,因为信用卡计费更改操作可能是一个webservice,而我们在测试中并不真的想联系信用卡公司 (2)因此,我们传递一个Payments对象给函数,使代码更加模块化

第2个程序class Cafe{ def buyCoffee(cc:CreditCard,p:Payments) : Coffee = { val cup = new Coffee() p.charge(cc,cup.price) // 这段代码出现副作用: cup } } (1)改进后的优点:虽然payments的实现可能还是需要调用远程webservice,但是测试代码时,可以使用mock创造一个不用远程调用的接口 (2)仍然存在的缺点:如果想买12杯咖啡,需要对函数循环12次,这样会进入12次计费计算过程,会导致效率急剧下降。;

函数式的代码写法 ``` class Cafe{ def buyCoffee(cc:CreditCard) : (Coffee,Charge) = { val cup = new Coffee() // p.charge(cc,cup.price) 删除这段 (cup,Charge(cc,cup.price)) } def buyCoffees(cc:CreditCard,n:Int):(List[Coffee],Charge) = { val purchases:List[(Coffee,Charge)] = List.fill(n)(buyCoffee(cc)) val (coffees,charges) = purchases.unzip(coffees,charges.reduce( (c1,c2)=>c1.add(c2) )) } }

case class Charge(cc:CreditCard,amount:Double){ def add(other:Charge):Charge = { // 累计计费,只能累计一个卡 if(cc==other.cc) Charge(cc,amount+other.amount) else throw new Exception("can't add different cards") } } ``` 【注】:函数式程序的标准写法:纯内核 + 很薄的外壳

三. 纯函数究竟是什么

引用透明:所谓引用透明的概念,就是指一个表达式,这个表达式在程序中可以被他的结果所取代,而不改变程序的含义纯函数:我们利用引用透明的概念定义了纯函数:               假设存在一个函数\(f\)和一个引用透明的表达式\(x\),若表达式\(f(x)\)对所有引用透明的表达式\(x\)也是引用透明的,那么\(f\)是一个纯函数

非纯函数,往往会破坏引用透明,使同一个表达式产生的结果并不相同,使人费解 (eg:1+1表达式永远为2,这就是引用透明,但有些java函数,并不是引用透明的,例如stringbuilder的相关方法)

scala> val x = new StringBuilder("Hello") x: StringBuilder = Hello scala> val r1 = x.append(" world") r1: StringBuilder = Hello world scala> val r2 = x.append(" world") // r2和r1的表达式一样,但是得到的结果却不同 r2: StringBuilder = Hello world world

转载于:https://www.cnblogs.com/moonlord/p/6273141.html

最新回复(0)