• 函数式编程


    函数式编程

    函数式编程(Functional Programming)之前都只是听说过,没有使用过所谓的函数式编程思想。不大理解这个概念。最近弄python的时候遇到了这个概念。

    函数式编程对应的是命令式编程(imperative programming)。我们平时写的程序大都属于这种编程方式:如果a大于b,就执行这个操作,否则的话,就执行这样的操作。我们一直研究的面向对象的编程也便是属于命令式编程的一种。

    函数式编程最重要的是一切都是函数。这里的一切包括什么?函数可以是变量么?可以。函数可以是返回值么?可以。

    高阶函数

    如果函数是变量,那么这个把函数当作变量的函数就是高阶函数。比如python中的这个函数:

    #!/usr/bin/python
    #coding:utf-8
    
    def g(f, a, b):
        return f(a, b)
    
    def add(a, b):
        return a + b
    
    val = g(add, 1, 2)
    print val
    

    其中g这个函数它就是高阶函数,他有一个参数为f。

    在python中,高阶函数的代表就是map和reduce。比如可以看下下面的例子:

    #!/usr/bin/python
    #coding:utf-8
    
    def f(a):
        return a * a
    
    def add(a, b):
        return a + b
    
    val1 = map(f, [1,2])
    val2 = reduce(add, val1)
    print val2
    
    

    在上面例子里面,map和reduce都是高阶函数,它们的第一个参数传递进去的是函数。但是当然上面的例子写的有点low,一点都不python,一般来说,我们使用匿名函数lambda来替换传递进来的参数。

    #!/usr/bin/python
    #coding:utf-8
    
    val1 = map(lambda x: x*x, [1,2])
    val2 = reduce(lambda x,y: x+y, val1)
    print val2
    
    

    这里引申的匿名函数的意思就很明显了。它就是函数的扩展。

    闭包

    高阶函数除了可以接受函数作为参数之外,还可以把函数作为返回值返回。

    #!/usr/bin/python
    #coding:utf-8
    
    def multi(a, b):
        def f():
            return a * a + b * b
        return f
    
    val = multi(1, 2)
    print val()
    
    

    把函数作为返回值,上面的例子在multi的时候其实并没有执行对应的计算,而是在print的时候才执行计算,这个是一种延迟行为。我们称之为惰性求职(lazy evaluation)。

    我们看到,在multi函数定义的a和b这两个局部变量,并不随着multi调用而销毁,在print这行,才具体执行的时候,a=1和b=2 还继续存在着。这就是“闭包”的威力。

    函数式编程

    回归到函数式编程,虽然说函数式编程是一种思维,和语言无关。但是只有实现了上述匿名函数,函数闭包等功能的语言才有函数式编程的能力。它最本质的观点是,所有的编程思想都是以函数为基本思想。

    首先,函数式编程认为每个函数都是封闭的,不依赖外部的数据,也不改变外部的数据。比如我们常用的OO里面的方法,函数式编程就觉得不合理。

    class A {
        public $isAuth = true;
    
        public isAuth(){
            return $this->isAuth;
        }
    }
    

    这里面的isAuth依赖外部的变量$isAuth,所以它是不符合函数式编程的函数封闭原理的。

    其次,函数像变量一样使用,这一点我们上面的部分已经说明清楚了。经常说的一句话是,函数是一等公民。

    比如像很多算法里面使用的递归算法,就算是函数式思维和非函数式思维的区别。比如计算斐波那契数列,从函数式思维开始思考,我们很容易思考到递归算法。而从其它思维出发,我们常常考虑的就是非递归解法。

    public static long fib(int n)
    {
      if(n <= 1)
         return n;
      else
          return fib(n-1) + fib(n-2);
    }
    

    从这个例子我们可以看出,使用函数式思想的一个好处,非常符合我们人类直观的理解。我们是要告诉程序要去做什么,而不是怎么去做。

    参考

    http://yangcongchufang.com/高级python编程基础/python-functional.html#dir2

    https://www.zhihu.com/question/28292740

    https://www.ibm.com/developerworks/cn/linux/l-cn-closure/index.html

    http://coolshell.cn/articles/10822.html

  • 相关阅读:
    UVALive 5983 MAGRID DP
    2015暑假训练(UVALive 5983
    poj 1426 Find The Multiple (BFS)
    poj 3126 Prime Path (BFS)
    poj 2251 Dungeon Master 3维bfs(水水)
    poj 3278 catch that cow BFS(基础水)
    poj3083 Children of the Candy Corn BFS&&DFS
    BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
    洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
    洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
  • 原文地址:https://www.cnblogs.com/yjf512/p/7240466.html
Copyright © 2020-2023  润新知