Closures, Currying, Partials in Scala
在FP里面很重要的三个理念:闭包,柯里化,偏函数;用Scala代码简单演示一下
Closures
wiki定义:闭包是由函数和与其相关的引用环境组合而成的实体.
字面意思不是很好理解,看下面这个例子
package otherscope { |
你会发现,定义sayHello()
的时候,没有入参hello
! 但是呢,环顾四周还是有定义的,重要的是不仅第一次exec调用时获取到值,第二次调用竟会神奇的感知到hello
的变更!
在闭包概念里,hello
这种类型的变量称为free variable
,看名字就不是一个简单变量,实际上它是一个引用,或者叫指针,所以才能感知外围变量值的变化
形象的两个比喻:文艺版,理工癌版
- 这就像两个恋人至死不渝,由于某些原因被分割天涯,但是爱情的魔力使他俩仍能感知彼此;这两个恋人就是那个闭包函数和那个
free variable
! - 量子纠缠: 粒子在由两个或两个以上粒子组成系统中相互影响的现象,虽然粒子在空间上可能分开. 爱因斯坦将量子纠缠称为“鬼魅似的远距作用”(spooky action at a distance)
同时也能看到FP里面实现闭包很简洁,因为天生支持高阶函数
Currying
wiki定义:是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术.
还是不直观,来看Scala例子
// Type: (Int,Int) => Int |
你会发现plus2
函数类型多了个=>
,这个符号表示转换,也就表明多了次转换;val p9 = plus2(9)_ => plus2(9)(y) => {9 + y}
; 所以p9(1) => 9 + 1 => 10
;
回头再看定义是不是就明白了,Currying就是你给了部分参数,然后会对部分入参进行运算(能算多少算多少)得到一个新函数,并且这个新函数的入参就是你没给的那些参数,这个新函数就叫curried function
Partials
wiki定义:a partial function from X to Y (written as f: X ↛ Y) is a function f: X ′ → Y, for some subset X ′ of X
说白了就是一个全函数(接受所有入参集合),但是只想拆分出来几个只能处理部分参数集合的子集函数
def minus(x: Int, y: Int) = {x - y} |
比如minus
是全函数,可以接收任何可能的(x,y)作为入参,但是我只想考虑(x=9,y=any)的入参集合,或者(x=any,y=9)的入参集合;可能这个不是很标准,Scala的标准做法是使用PartialFunction
,感兴趣的话可以参考Reference