国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

函數式編程(三)

seasonley / 684人閱讀

摘要:前面兩節介紹了純函數和高階函數,在函數式編程中,函數就是我們的磚塊。參數順序是能否最大程度利用柯里化的關鍵所在。

前面兩節介紹了純函數和高階函數,在函數式編程中,函數就是我們的磚塊。我們編寫一些可以完成非常具體任務的函數,然后像樂高積木一樣將他們搭建起來。

這就是所謂的函數組合。

函數組合

先看兩個純函數

let add10 = value => value + 10;
let mult5 = value => value * 5;

let mult5AfterAdd10 = value => mult5(add10(value)) 

這樣寫代碼很容易寫出h(g(f(e(x)))),這樣層層相套的代碼,一層一層撥開它的心。
為了解函數嵌套的問題,我們可以先預定義一個組合函數

var compose = function(f,g) {
  return function(x) {
    return f(g(x));
  };
};

然后改寫上面的例子

let mult5AfterAdd10 = compose(mult5, add10)
mult5AfterAdd10(5)

這樣做的可讀性遠遠高于嵌套一大堆的函數調用。

Point Free

把一些對象自帶的方法轉化為純函數,不要命名轉瞬即逝的中間變量

網上有很多關于Point Free的案例,我認為都不怎么能說明問題,下面這個例子是我精心準備的機密,一般不外傳。

const f = str => str.toUpperCase().split("");
const toUpperCase = word => word.toUpperCase();
const split = x => (str => str.split(x));


const f = compose(split(""), toUpperCase)

f("aa vv")
//我們沒有使用到str變量

我們不需要指定冗余的參數。由于不必指定參數,所以也就不必考慮為它們命名。其次,由于更簡短使得更容易閱讀。Pointfree 的本質就是使用一些通用的函數,組合出各種復雜運算。上層運算不要直接操作數據,而是通過底層函數去處理。這就要求,將一些常用的操作封裝成函數。所以說這種方式慎用。

看到這里你是不是以為自己就了解函數式編程了呢?nonono?下面我有個問題想考考你。

let add = (value, y) => value + y;
let mult5 = value => value * 5;

我想改寫上面的mult5AfterAdd10函數,把它轉成更通用的mult5AfterAdd,你想到用上面學到的姿勢,

let mult5AfterAdd = compose(mult5, add) 

顯然這個不行的,因為add函數需要接收兩個參數,實際只傳遞了一個參數,所以它會將一個錯誤的結果傳遞給mult5。這最終會產生一個錯誤的結果。
我們怎么解決這個問題?事實證明有一種方法,它就是柯里化(Currying)

下面我們來看看函數的柯里化。
有這樣一道題目,實現一個函數,實現如下功能:

var result = sum(1)(2)(3);
console.log(result);//6

以下是一種實現方式

function add(a){
    var sum = 0;
        sum += a;
    return b => {
        sum += b;
        return c => {
            sum += c;
            return sum;
        }
    }
}
add(1)(2)(3);//6

我們來解決上面遺留的問題,通過改寫add函數

let add = x => y => x + y
let compose = (f, g) => x => f(g(x));
let mult5AfterAdd10 = compose(mult5, add(10));

我們就是將簡單常見的add函數轉化成了柯里化函數,這樣add函數就變得更加自由靈活了。我們先將第1個參數10輸入,而當mult5AfterAdd10函數被調用的時候,最后1個參數才有了確定的值。

柯里化

柯里化通常也稱部分求值,其含義是給函數分步傳遞參數,每次傳遞參數后,部分應用參數,并返回一個更具體的函數接受剩下的參數,中間可嵌套多層這樣的接受部分參數函數,逐步縮小函數的適用范圍,逐步求解,直至返回最后結果。

一個簡單的通用模塊的函數柯里化封裝

const curry = fn => {
    const _args = [];
    return function cb() {

        if(arguments.length === 0) {
            return fn.apply(this, _args);
        }

        Array.prototype.push.apply(_args, [...arguments]);

        return cb;
    }
}


函數柯里化是一種預加載函數的方法,通過傳遞較少的參數,得到一個已經記住了這些參數的新函數,某種意義上來講,這是一種對參數的“緩存”,是一種非常高效的編寫函數的方法。??參數順序是能否最大程度利用柯里化的關鍵所在。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82886.html

相關文章

  • JavaScript面向對象編程-繼承(

    摘要:子類不是父類實例的問題是由類式繼承引起的。所以寄生式繼承和構造函數繼承的組合又稱為一種新的繼承方式。但是這里的寄生式繼承處理的不是對象,而是類的原型。看上去略微復雜,還得好好研究。 寄生組合式繼承(終極繼承者) 前面學習了類式繼承和構造函數繼承組合使用,也就是組合繼承,但是這種繼承方式有個問題,就是子類不是父類的實例,而子類的原型是父類的實例。子類不是父類實例的問題是由類式繼承引起的。...

    alaege 評論0 收藏0
  • gitbook: 前端好書推薦

    摘要:它大致概述并討論了前端工程的實踐如何學習它,以及在年實踐時使用什么工具。目的是每年發布一次內容更新。前端實踐第一部分廣泛描述了前端工程的實踐。對大多數人來說,函數式編程看起來更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 這是任何人都可以用來了解前端開發實踐的指南。它大致概述并...

    Ali_ 評論0 收藏0
  • gitbook: 前端好書推薦

    摘要:它大致概述并討論了前端工程的實踐如何學習它,以及在年實踐時使用什么工具。目的是每年發布一次內容更新。前端實踐第一部分廣泛描述了前端工程的實踐。對大多數人來說,函數式編程看起來更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 這是任何人都可以用來了解前端開發實踐的指南。它大致概述并...

    CocoaChina 評論0 收藏0
  • gitbook: 前端好書推薦

    摘要:它大致概述并討論了前端工程的實踐如何學習它,以及在年實踐時使用什么工具。目的是每年發布一次內容更新。前端實踐第一部分廣泛描述了前端工程的實踐。對大多數人來說,函數式編程看起來更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 這是任何人都可以用來了解前端開發實踐的指南。它大致概述并...

    Warren 評論0 收藏0
  • SegmentFault 技術周刊 Vol.16 - 淺入淺出 JavaScript 函數編程

    摘要:函數式編程,一看這個詞,簡直就是學院派的典范。所以這期周刊,我們就重點引入的函數式編程,淺入淺出,一窺函數式編程的思想,可能讓你對編程語言的理解更加融會貫通一些。但從根本上來說,函數式編程就是關于如使用通用的可復用函數進行組合編程。 showImg(https://segmentfault.com/img/bVGQuc); 函數式編程(Functional Programming),一...

    csRyan 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<