zoukankan      html  css  js  c++  java
  • 什么是函数式编程?

     

    纯函数:

    定义: 对于相同的输入永远会得到相同的输出,而且没有任何可以观察的副作用,也不依赖外部的环境状态。

    例如数学公式: y=f(x)

    在javascript中,对于数组的操作,有的是纯的,有的是不存的,如:

    let arr = [1,2,3,4,5];
    
    // 纯函数
    arr.slice(0,3); // [1,2,3]
    arr.slice(0,3); // [1,2,3]
    
    // 非纯函数
    arr.splice(0,3); // [1,2,3]
    arr.splice(0,3); // [4,5]

    编程式函数为何排斥不纯的函数?

    非纯函数中,函数的行为需要由外部的系统环境影响。也就是说函数不仅仅由输入的参数决定,还可能因为外部的某些变量影响。

    这种对于外部状态的依赖,是造成系统复杂性大大提高的关键。

    举个例子:

    let timeOfLife = 20;
    
    // 纯函数
    function test(age) {
       return age > 20;
    }
    
    // 非纯函数
    function test2(age) {
      return age > timeOfLife;  
    }

    这个例子中非纯函数就依赖于外部的变量timeOfLife

    函数柯里化

    定义: 向函数传递一个参数去调用他,返回一个方法去处理剩下的参数。

    柯里化的实质是“预加载”函数的方法,向方法传递较少的参数,得到一个已经记住这些参数的新函数,某种意义上讲,这是一种对参数的”缓存“,是一种非常高效的编写函数的方法。

    举个例子:

    let timeOfLife = 20;
    
    function test(timeOfLife) {
       return function(age) {
         return age > timeOfLife   
      }  
    } 
    let testing = test(20);  
    testing(19);  // false

    函数组合

    未避免写出不优雅的包菜式函数: h(g(f(x))) , 我们需要用到函数组合。

    function compose(f, g) {
      return function (x) {
        return  g(f(x));            
      }
    }
     
    let mult = function (num) {
      return num * 5;
    }
    
    let add = function (num) {
      return add + 1;
    }
    
    compose(mult, add)(2);  // 15

    我们定义的compose就像双面胶一样,可以把任意两个函数结合在一起,也可以扩展出n个函数的n个胶面。

    这种灵活的组合方式,我们可以向拼积木一样优雅的组合函数式代码。

    声明式与命令式

    命令式代码: 通过一条有一条指令,让计算机执行一系列动作,其中一般会涉及很多繁琐的细节。

    声明式代码: 通过写表达式的方式,声明我们想要干什么,而不是一步一步的指示。

    // 命令式
    let rest = [];
    let arr = [1,2,3,4,5];
    for(var i = 1; i< arr.length; i++) {
      if(rest.indexOf(arr[i]) === -1) {
          rest.push(arr[i]);
      }  
    }
        
    
    // 声明式
    var test = arr.map(Math.sqrt)

    声明式代码是函数式编程一个明显的好处: 编写、优化代码时能更加专注。

    总结

    1. 函数对于外部的依赖,是造成系统复杂性大大提高的原因

    2. 代码中书写纯函数尽可能纯净

    3. 函数式编程不是万能的,他与OOP一样,只是一种编程范式

    4. 为降低软件的复杂度,OOP是靠良好的封装,继承,多态以及接口的定义。 函数式编程则是靠纯函数以及他们的组合、柯里化技术

    ...

  • 相关阅读:
    [2016北京集训试题15]项链-[FFT]
    [agc008E]Next or Nextnext-[dp+思考题]
    [agc011E]Increasing Numbers-[思考题]
    [2016北京集训试题14]股神小D-[LCT]
    [2016北京集训试题6]mushroom-[bitset]
    [2016北京集训试题6]魔法游戏-[博弈论-sg函数]
    [arc081F]Flip and Rectangles-[黑白染色]
    [arc072F]Dam-[单调队列]
    【CF787D】遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)
    【CF373C】计算袋鼠是愉快的(Counting Kangaroos is Fun)-贪心
  • 原文地址:https://www.cnblogs.com/zzd0916/p/12230884.html
Copyright © 2011-2022 走看看