所有函數(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
预愤,A
和B
都是base/1
函數(shù)作用域的一部分沟于,這意味著在base/1
中的任何地方都可以引用A
和B
,任何地方也包括匿名函數(shù)base(A) -> B = A + 1, F = fun() -> A * B end, F().
這個例子中植康,
A
和B
仍然在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 ...
Erlang極簡學習筆記<06>——高階函數(shù)篇
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赞季,“玉大人愧捕,你說我怎么就攤上這事∩旯常” “怎么了次绘?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我邮偎,道長管跺,這世上最難降的妖魔是什么? 我笑而不...
- 正文 為了忘掉前任禾进,我火速辦了婚禮豁跑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泻云。我一直安慰自己艇拍,他們只是感情好,可當我...
- 文/花漫 我一把揭開白布宠纯。 她就那樣靜靜地躺著卸夕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪婆瓜。 梳的紋絲不亂的頭發(fā)上快集,一...
- 文/蒼蘭香墨 我猛地睜開眼晕讲,長吁一口氣:“原來是場噩夢啊……” “哼覆获!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瓢省,我...
- 正文 年R本政府宣布山害,位于F島的核電站,受9級特大地震影響沿量,放射性物質(zhì)發(fā)生泄漏浪慌。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一朴则、第九天 我趴在偏房一處隱蔽的房頂上張望权纤。 院中可真熱鬧,春花似錦佛掖、人聲如沸妖碉。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坐榆,卻和暖如春拴魄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背席镀。 一陣腳步聲響...
推薦閱讀更多精彩內(nèi)容
- 本文是在學習和使用kotlin時的一些總結(jié)與體會,一些代碼示例來自于網(wǎng)絡(luò)或Kotlin官方文檔交播,持續(xù)更新... 對...
- 原文鏈接:https://github.com/EasyKotlin 值就是函數(shù)重虑,函數(shù)就是值。所有函數(shù)都消費函數(shù)秦士,...
- JavaScript的相關(guān)語法知識:1缺厉、函數(shù)(important)基本上所有的高級語言(C、OC隧土、JavaScri...