您好,登錄后才能下訂單哦!
今天小編給大家分享一下C語(yǔ)言函數(shù)加里化和偏函數(shù)應(yīng)用實(shí)例分析的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
【名詞解釋】Currying:因?yàn)槭敲绹?guó)數(shù)理邏輯學(xué)家哈斯凱爾·加里(Haskell Curry)發(fā)明了這種函數(shù)使用技巧,所以這樣用法就以他的名字命名為Currying,中文翻譯為“加里化”。
我感覺(jué)很多人都對(duì)函數(shù)加里化(Currying)和偏函數(shù)應(yīng)用(Partial Application)之間的區(qū)別搞不清楚,尤其是在相似的上下文環(huán)境中它們同時(shí)出現(xiàn)的時(shí)候。
偏函數(shù)解決這樣的問(wèn)題:如果我們有函數(shù)是多個(gè)參數(shù)的,我們希望能固定其中某幾個(gè)參數(shù)的值。
幾乎所有編程語(yǔ)言中都有非常明顯的偏函數(shù)應(yīng)用。在C語(yǔ)言中:
int foo(int a, int b, int c) { return a + b + c; } int foo23(int a, int c) { return foo(a, 23, c); }
foo23
函數(shù)實(shí)際上就是一個(gè)foo
函數(shù)的偏函數(shù)應(yīng)用,參數(shù)b
的值被固定為23。
當(dāng)然,像這樣明顯的偏函數(shù)并沒(méi)有太大的用處;我們通常會(huì)希望編程語(yǔ)言能提供我們某些偏函數(shù)特征。
例如,在Python語(yǔ)言中,我們可以這樣做:
from functools import partial def foo(a,b,c): return a + b + c foo23 = partial(foo, b=23) foo23(a = 1, c = 3) # => 27
函數(shù)加里化(Currying)明顯解決的是一個(gè)完全不同的問(wèn)題:如果我們有幾個(gè)單參數(shù)函數(shù),并且這是一種支持一等函數(shù)(first-class)的語(yǔ)言,如何去實(shí)現(xiàn)一個(gè)多參數(shù)函數(shù)?函數(shù)加里化是一種實(shí)現(xiàn)多參數(shù)函數(shù)的方法。
下面是一個(gè)單參數(shù)的Javascript函數(shù):
var foo = function(a) { return a * a; }
如果我們受限只能寫(xiě)單參數(shù)函數(shù),可以像下面這樣模擬出一個(gè)多參數(shù)函數(shù):
var foo = function(a) { return function(b) { return a * a + b * b; } }
通過(guò)這樣調(diào)用它:(foo(3))(4)
,或直接 foo(3)(4)
。
注意,函數(shù)加里化提供了一種非常自然的方式來(lái)實(shí)現(xiàn)某些偏函數(shù)應(yīng)用。如果你希望函數(shù)foo
的***個(gè)參數(shù)值被固定成5,你需要做的就是var foo5 = foo(5)
。這就OK了。函數(shù)foo5
就是foo
函數(shù)的偏函數(shù)。注意,盡管如此,我們沒(méi)有很簡(jiǎn)單的方法對(duì)foo
函數(shù)的第二個(gè)參數(shù)偏函數(shù)化(除非先偏函數(shù)化***個(gè)參數(shù))。
當(dāng)然,Javascript是支持多參數(shù)函數(shù)的:
var bar = function(a, b) { return a * a + b * b; }
我們定義的bar
函數(shù)并不是一個(gè)加里化的函數(shù)。調(diào)用bar(5)
并不會(huì)返回一個(gè)可以輸入12的函數(shù)。我們只能像bar(5,12)
這樣調(diào)用這個(gè)函數(shù)。
在一些其它語(yǔ)言里,比如 Haskell 和 OCaml,所有的多參數(shù)函數(shù)都是通過(guò)加里化實(shí)現(xiàn)的。
下面是一個(gè)把上面的foo
函數(shù)用OCaml語(yǔ)言寫(xiě)成的例子:
let foo = fun a -> fun b -> a * a + b * b
下面是把上面的bar
函數(shù)用OCaml語(yǔ)言寫(xiě)成的例子:
let bar = fun a b -> a * a + b * b
頭一個(gè)函數(shù)我們叫做“顯式加里化”,第二個(gè)叫做“隱式加里化”。
跟Javascript不一樣,在OCaml語(yǔ)言里,foo
函數(shù)和bar
函數(shù)是完全一樣的。我們用完全一樣的方式調(diào)用它們。
# foo 3 4;; - : int = 25 # bar 3 4;; - : int = 25
兩個(gè)函數(shù)都能夠通過(guò)提供一個(gè)參數(shù)值來(lái)創(chuàng)造一個(gè)偏函數(shù):
# let foo5 = foo 5;; val foo5 : int -> int = <fun> # let bar5 = bar 5;; val bar5 : int -> int = <fun> # foo5 12;; - : int = 169 # bar5 12;; - : int = 169
事實(shí)上,我們可以把下面這個(gè)匿名函數(shù):
fun arg1 arg2 ... argN -> exp
當(dāng)作是下面這個(gè)函數(shù)的簡(jiǎn)寫(xiě):
fun arg1 -> fun arg2 -> ... -> fun argN -> exp
以上就是“C語(yǔ)言函數(shù)加里化和偏函數(shù)應(yīng)用實(shí)例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。