函数式编程应用的窗户纸

原创文章转载请注明出处

关于函数式编程的概念这里不做深入介绍,这里要讲的是函数式编程的部分应用场景,如果下面这些内容你都了解了,那么再去看函数式编程的介绍你就可以很快的理解了,甚至你可能发现自己在不知不觉中已经使用了很多函数式编程的技巧了。

1. map、reduce、filter...#

函数式编程最常见的技术就是对一个集合做Map、Reduce和Filter操作,map对集合成员做了映射操作,生成新的集合;reduce就是降维操作,化整为零;filter顾名思义通过过滤器生成新的集合。
Python

map(lambda x: x ** 2, [1, 2, 3, 4, 5])
filter(lambda x: x & 1 != 0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
reduce(lambda x, y: x + y, [2, 3, 4, 5, 6], 1)  #((((((1+2)+3)+4)+5)+6))

Swift

[1, 2, 3, 4, 5].map { i in return i*i }
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].filter { (i) -> Bool in return i & 1 != 0 }
[2, 3, 4, 5, 6].reduce(1) { (result, i) -> Int in return result + i }

这里不深究Swift的闭包语法,我知道尾随闭包可以简写。
以上两种语言的代码,转换后输出的结果都是:

[1, 4, 9, 16, 25]
[1, 3, 5, 7, 9]
21

我们将函数作为参数传给了map/filter/reduce函数,告诉这些函数你们要对数组元素进行什么操作,而不是使用低级的循环迭代方式来操作数组元素。变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数,函数式编程就是指这种高度抽象的编程范式。

2. currying 柯里化##

柯里化 (Currying),也就是把接受多个参数的方法变换成接受第一个参数的方法,并且返回接受余下的参数而且返回结果的新方法。
Python

def inc(x):
    def incx(y):
        return x+y
    return incx
 
inc2 = inc(2)
inc5 = inc(5)
 
print inc2(5) # 输出 7
print inc5(5) # 输出 10

Swift

//下面这种Currying语法在Swift 3.0已经被移除了。
//func inc(x: Int)(y: Int) -> Int { return x + y } 
//你可以这么写,看起来跟Python的样式比较接近
func inc(x:Int) -> ((Int) -> Int) {
    return { y in
        return x + y
    }
}
let inc2 = inc(x: 2)
let inc5 = inc(x: 5)
print(inc2(5))

↑函数式编程的特点:把函数当成变量来用。

函数式编程的应用场景还有许多,这里没有全部列出,诸如递归、惰性求值(Lazy)等。也许你自己都不知道已经在不知不觉的使用着函数式编程,看完上面的介绍是不是更能体会到函数式编程的思维逻辑?

需要注意的是,FP(函数式编程)和FRP(函数响应式编程)是有差别的,我的理解是FRP是FP的更高级应用,FRP提供了一种信号机制,通过信号来记录值的变化。信号可以被叠加、分割或合并,通过对信号的组合,就不需要去监听某个值或事件。至于MVVM,那是一种应用FRP实现的开发模型,以区别于传统的MVC模型。比如iOS上的RAC/RxSwift都是FRP框架,可以利用RAC/RxSwift来实现MVVM开发模型。

我是咕咕鸡,一个还在不停学习的全栈工程师。
热爱生活,喜欢跑步,家庭是我不断向前进步的动力。

你可能感兴趣的:(函数式编程应用的窗户纸)