Erlang極簡學習筆記<06>——高階函數(shù)篇

  • 所有函數(shù)式語言都具有一個重要的特性:把自定義函數(shù)作為參數(shù)傳遞給另一個函數(shù)锋恬。這個函數(shù)參數(shù)會被綁定到一個變量上守伸,在函數(shù)內(nèi)部可以像使用其他變量一樣使用這個變量。如果一個函數(shù)的參數(shù)是以這種方式傳過來的其他函數(shù),則稱之為高階函數(shù)(higher-order function)

  • 高階函數(shù)是一種強有力的抽象手段,也是Erlang提供的眾多出色工具中需要熟練掌握的一個

  • 函數(shù)可以攜帶并且可以作為參數(shù)傳遞給高階函數(shù)的思想起源于數(shù)學顽馋,主要來自Lambda演算

  • 本質(zhì)上,純Lambda演算中的所有東西都是函數(shù)幌羞,就連數(shù)字寸谜、操作符和列表也都是函數(shù)。因為所有東西都被表示成函數(shù)属桦,所以函數(shù)必須能接收其他函數(shù)作為參數(shù)熊痴,還必須能用函數(shù)來操作函數(shù)

    -module(hhfuns).
    -compile(export_all).
    
    one() -> 1.
    two() -> 2.
    
    add(X,Y) -> X() + Y().
    
    Eshell
    > c(hhfuns).
    > hhfuns:add(fun hhfuns:one/0, fun hhfuns:two/0).
    
  • Module:Function/Arity告訴VM去使用這個指定的函數(shù),并把這個函數(shù)綁定到一個變量上

    increment([]) -> [];
    increment([H|T]) -> [H+1 | increment(T)].
    
    decrement([]) -> [];
    decrement([H|T]) -> [H-1 | decrement(T)].
    
    Eshell
    > c(hhfuns).
    > L = [1,2,3,4,5].
    > hhfuns:increment(L).
    > hhfuns:decrement(L).
    
  • 上面2個函數(shù)做的事情大致相同:循環(huán)遍歷列表聂宾,在每個元素上應(yīng)用一個函數(shù)(+-)果善,然后再調(diào)用自身

    map(_, []) -> [];
    map(F, [H|T]) -> [F(H) | map(F, T)].
    
    incr(X) -> X+1.
    decr(X) -> X-1.
    
    Eshell
    > c(hhfuns).
    > L = [1,2,3,4,5].
    > hhfuns:map(fun hhfuns:incr/1, L).
    > hhfuns:map(fun hhfuns:decr/1, L).
    
  • 我們將流程中相同的部分抽取出來放在一個單獨的函數(shù)map/2中,這個函數(shù)接收另外一個函數(shù)作為參數(shù)

  • map/2是一個更聰明的抽象系谐,每當我們想把一個函數(shù)應(yīng)用于列表中的每個元素上時巾陕,只需以這個函數(shù)為參數(shù)調(diào)用map/2即可

  • 匿名函數(shù)(anonymous functions)又稱funs,是在行間定義的一種特殊函數(shù),無需給其取名惜论,從而解決了函數(shù)作為參數(shù)的那些麻煩問題

  • 正常函數(shù)能做的事情,匿名函數(shù)基本上也都可以完成止喷,除了不能遞歸調(diào)用自己馆类。語法如下:

    fun (Args1) ->
        Expression1, Expression2, ..., ExpressionN;
        (Args2) ->
        Expression1, Expression2, ..., ExpressionN;
        (Args3) ->
        Expression1, Expression2, ..., ExpressionN
    end
    
  • 函數(shù)式編程可以對非常低層次的代碼進行抽象。因此可以完全忽略像循環(huán)這種基本概念弹谁,從而聚焦在做什么上乾巧,而不是怎么做

    Eshell
    > hhfuns:map(fun(X) -> X+1 end, L).
    > hhfuns:map(fun(X) -> X-1 end, L).
    
  • 可以把函數(shù)的作用域想象成存放所有變量及這些變量對應(yīng)值的地方。例如base(A) -> B = A+1预愤,AB都是base/1函數(shù)作用域的一部分沟于,這意味著在base/1中的任何地方都可以引用AB,任何地方也包括匿名函數(shù)

    base(A) ->
        B = A + 1,
        F = fun() -> A * B end,
        F().
    
  • 這個例子中植康,AB仍然在base/1的作用域范圍之內(nèi)旷太,所以函數(shù)F可以訪問到它們。這是因為F繼承了base/1的作用域

  • 不管匿名函數(shù)在哪里销睁,這個被繼承的作用域會一直跟隨著它供璧,即使把這個匿名函數(shù)傳遞給另外的一個函數(shù)

  • 如果函數(shù)具有多個參數(shù),但是其中有一個參數(shù)一直保持不變冻记,那么此時就很適合使用匿名函數(shù)來攜帶狀態(tài)

    Eshell
    > Base = 2.
    > PowerOfTwo = fun(X) -> math:pow(Base, X) end.
    > hhfuns:map(PowerOfTwo, L).
    
  • 閉包指的是可以讓函數(shù)引用到它所攜帶的某些環(huán)境(作用域中的值部分)睡毒。換句話說,當匿名函數(shù)冗栗、作用域的概念以及可以攜帶變量的能力結(jié)合在一起時演顾,閉包就出現(xiàn)了

  • Erlang標準庫已經(jīng)提供了許多基于列表的抽象(參見文檔

    lists:map/2, lists:filter/2, lists:foldl/3, lists:foldr/3
    all/2, any/2, dropwhile/2, takewhile/2, partition/2, 
    flatten/1, flatlength/1, flatmap/2, merge/1, 
    nth/2, nthtail/2, split/2, zip/2, unzip/1 ... 
    

原文地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市隅居,隨后出現(xiàn)的幾起案子钠至,更是在濱河造成了極大的恐慌,老刑警劉巖胎源,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棕洋,死亡現(xiàn)場離奇詭異,居然都是意外死亡乒融,警方通過查閱死者的電腦和手機掰盘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赞季,“玉大人愧捕,你說我怎么就攤上這事∩旯常” “怎么了次绘?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我邮偎,道長管跺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任禾进,我火速辦了婚禮豁跑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泻云。我一直安慰自己艇拍,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布宠纯。 她就那樣靜靜地躺著卸夕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪婆瓜。 梳的紋絲不亂的頭發(fā)上快集,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音廉白,去河邊找鬼碍讨。 笑死,一個胖子當著我的面吹牛蒙秒,可吹牛的內(nèi)容都是我干的勃黍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼晕讲,長吁一口氣:“原來是場噩夢啊……” “哼覆获!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瓢省,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤弄息,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后勤婚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摹量,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年馒胆,在試婚紗的時候發(fā)現(xiàn)自己被綠了缨称。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡祝迂,死狀恐怖睦尽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情型雳,我是刑警寧澤当凡,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布山害,位于F島的核電站,受9級特大地震影響沿量,放射性物質(zhì)發(fā)生泄漏浪慌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一朴则、第九天 我趴在偏房一處隱蔽的房頂上張望权纤。 院中可真熱鬧,春花似錦佛掖、人聲如沸妖碉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坐榆,卻和暖如春拴魄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背席镀。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工匹中, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人豪诲。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓顶捷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親屎篱。 傳聞我的和親對象是個殘疾皇子服赎,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

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