函數(shù)式編程101(一)

函數(shù)式編程這幾年變得越來(lái)越流行起來(lái),越來(lái)越多的語(yǔ)音融入了函數(shù)式編程的語(yǔ)法,就連更新緩慢如Java也不例外,在Java8中引入了函數(shù)式編程的語(yǔ)法袍祖。JVM平臺(tái)的后起之秀Scala,Groovy更是出生之初就有內(nèi)置了對(duì)函數(shù)式編程的支持谢揪。作為最經(jīng)常被拿來(lái)與Java做比較的C#蕉陋,更是搶先一步在.NET 3.5版本時(shí)就有了對(duì)函數(shù)式編程的支持。后來(lái).NET平臺(tái)上更是直接引入了函數(shù)式編程語(yǔ)言F#拨扶。

函數(shù)式編程的興起并非沒(méi)有原因凳鬓。

  • 函數(shù)式編程語(yǔ)言一般極具表現(xiàn)力. 相比主流的面向?qū)ο笳Z(yǔ)言能以極少的代碼完成相同的工作。與代碼量的減少相對(duì)應(yīng)的就是維護(hù)成本的降低患民。
  • 相對(duì)于命令式編程缩举,函數(shù)式編程語(yǔ)言都是采用聲明式編程的方式,能在更高的抽象級(jí)別上編程匹颤,代碼更易于理解仅孩。
  • 純函數(shù)是沒(méi)有副作用的,既不會(huì)修改全局狀態(tài)印蓖,也不會(huì)修改傳入的參數(shù)辽慕。在進(jìn)行多線程編程時(shí),就從根本上避免死鎖赦肃,活鎖或者是線程饑餓的問(wèn)題溅蛉。

函數(shù)式編程語(yǔ)言的特征

高階函數(shù)

在函數(shù)式編程語(yǔ)言中,函數(shù)終于成為一等公民他宛,可以跟變量一樣作為參數(shù)傳遞船侧,同時(shí)也可以作為函數(shù)返回值返回。這個(gè)功能帶來(lái)的直接好處就是當(dāng)我們需要傳遞行為的時(shí)候厅各,不必在跟之前一樣為了傳遞行為而引入一個(gè)對(duì)象镜撩。例如在Java 8之前,當(dāng)我們想排序一個(gè)List時(shí):

    List<Integer> values = newArrayList(11, 2, 43, 14, 5, 76, 6);
    Collections.sort(values, new Comparator<Integer>() {
        @Override
        public int compare(Integer one, Integer other) {
            return one.compareTo(other);
        }
    });     

Java 8引入了Lambda之后队塘,我們不必再引入一個(gè)對(duì)象來(lái)封裝我們的排序邏輯:

    Collections.sort(values, (a, b) -> a.compareTo(b));

本質(zhì)上講琐鲁,傳遞進(jìn)來(lái)的還是一個(gè)對(duì)象卫旱,只不過(guò)是因?yàn)镕unctional Interface的存在,我們可以假裝傳入的是一個(gè)函數(shù)围段。這一點(diǎn)在我們使用傳入的對(duì)象時(shí)就更為明顯: 我們不得不像使用對(duì)象一樣通過(guò)調(diào)用apply方法來(lái)應(yīng)用傳入的函數(shù)

    public static <T> T create(String stringValue, Function<String, T> instantiator) {
        return instantiator.apply(stringValue);
    }

在純粹的函數(shù)式編程語(yǔ)言中投放,高階函數(shù)的使用則更為自然奈泪, 如在haskell中,

    add :: a -> a -> a
    add a b = a + b

    perform :: a -> a -> (a -> a -> a) -> a
    perform a b action = action a b

    let result = perform 1 1 add    
    // result = 2

既然函數(shù)可以作為參數(shù)傳遞灸芳,也可以作為返回值涝桅,那么函數(shù)之間的運(yùn)算也就不足為奇了。以下是Haskell中用來(lái)組合(compose)函數(shù)的函數(shù)(對(duì)烙样,這里沒(méi)有寫錯(cuò)冯遂,就是通過(guò)組合函數(shù)來(lái)生成更強(qiáng)大函數(shù))。

    (.) :: (b -> c) -> (a -> b) -> a -> c
    (.) f g x = f(g(x))

利用(.)谒获,我們可以對(duì)函數(shù)進(jìn)行組合:

    plus :: a -> a
    plus x = x + 1

    double :: a -> a
    double x = x * 2

    plusThenDouble = double.plus

    let result = plusThenDouble 1
    // result = 4

科里化(Currying)

科里化把一個(gè)(接收多個(gè)參數(shù)的函數(shù))的運(yùn)算轉(zhuǎn)化為多個(gè)(只接收一個(gè)參數(shù)的函數(shù))的運(yùn)算蛤肌。例如:

    add :: a -> a -> a
    add a b = a + b

函數(shù)add接收兩個(gè)參數(shù),返回兩者的和批狱。我們可以把函數(shù)add理解為接收一個(gè)參數(shù)a裸准,然后返回一個(gè)函數(shù)addA。函數(shù)B接收另外一個(gè)參數(shù)B, 返回值則是A+B赔硫。那么1+2的例子就可以如下所示:

   add1 :: a -> a
   add1 = add 1

   let result = add1 2 // result = 3

上面的例子中add1其實(shí)就是一個(gè)部分應(yīng)用函數(shù)(Partial Applied Function)炒俱。

其實(shí)這就是函數(shù)式編程語(yǔ)言中代碼重用的方式。面向?qū)ο笳Z(yǔ)言通過(guò)繼承和組合重用已有邏輯爪膊,函數(shù)式語(yǔ)言可以通過(guò)部分應(yīng)用函數(shù)以及函數(shù)組合來(lái)實(shí)現(xiàn)代碼復(fù)用权悟。

本篇文章是函數(shù)式編程系列之一:

  1. 函數(shù)式編程 101
  2. 函數(shù)式編程 101 (續(xù))
  3. 函數(shù)式編程初體驗(yàn) 一
  4. 函數(shù)式編程初體驗(yàn) 二
  5. 函數(shù)式編程初體驗(yàn) 三
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市推盛,隨后出現(xiàn)的幾起案子峦阁,更是在濱河造成了極大的恐慌,老刑警劉巖小槐,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拇派,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡凿跳,警方通過(guò)查閱死者的電腦和手機(jī)件豌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)控嗜,“玉大人茧彤,你說(shuō)我怎么就攤上這事〗福” “怎么了曾掂?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵惫谤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我珠洗,道長(zhǎng)溜歪,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任许蓖,我火速辦了婚禮蝴猪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘膊爪。我一直安慰自己自阱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布米酬。 她就那樣靜靜地躺著沛豌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赃额。 梳的紋絲不亂的頭發(fā)上加派,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音爬早,去河邊找鬼哼丈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛筛严,可吹牛的內(nèi)容都是我干的醉旦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼桨啃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼车胡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起照瘾,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤匈棘,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后析命,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體主卫,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年鹃愤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了簇搅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡软吐,死狀恐怖瘩将,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤姿现,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布肠仪,位于F島的核電站,受9級(jí)特大地震影響备典,放射性物質(zhì)發(fā)生泄漏异旧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一提佣、第九天 我趴在偏房一處隱蔽的房頂上張望泽艘。 院中可真熱鬧,春花似錦镐依、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至喜每,卻和暖如春务唐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背带兜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工枫笛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刚照。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓刑巧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親无畔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子啊楚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容