如何理解functional programming裡的currying與partial application

時間 2021-05-05 22:55:08

1樓:李欣宜

定義乙個多參函式f(arg1,arg2……argn)時,如果每個引數argi的型別為ti,這個多參函式最後的返回結果的型別為rtype,那麼可以說f的型別為

(t1 * t2 * ... * tn) -> rtype

這是很多語言對於多參函式的解釋,把這些引數作為乙個tuple或者list傳入,即(t1 * t2 * ... * tn)型別的值(arg1 * arg2 * ... *argn)作為它的實參。

Currying把多參函式轉換成多個單參函式的巢狀,整個f的型別從此變為:

t1 -> (t2 -> (... ->(tn -> rtype)...))

這裡也是為了讓你看的更清才特定加的括號,->運算子本來就是右結合的,int->int->int就是int->(int->int),引數為int,返回乙個引數為int且返回int的函式。如果不習慣把函式也當作可以被返回的頭等公民,初見這種表達可能會覺得有點繞,沒關係,慢慢來,上面的f需要被傳入乙個t1型別的引數,返回乙個以t2型別作為唯一引數的函式,而這個函式又以t3型別作為唯一引數,返回乙個函式,返回的函式又以t4型別作為引數……直至n層函式定義後,返回結果為原來的rtype型別的值。

像ML這樣的語言,函式都是單參的,實現乙個多參函式可以像前者把引數們打包成乙個tuple傳入,比如檢查x,y,z是否為公升序可以通常寫為

funsorted3_tupled(x

,y,z

)=z>=yandalso

y>=x也可以像後者curry為單參函式的巢狀:

valsorted3=fn

x=>fny

=>fnz

=>z>=yandalso

y>=x總的來說,執行多參函式的時間還是正比於引數的個數,所以在performance方面,一次傳入所有引數來執行同乙個函式的curried版本或者uncurried版本,沒那麼大區別。當然如果你特別在意某些多參函式的效率,到底currying會帶來怎樣的變化依然需要具體問題具體分析,比如在ML的編譯器中用tuple會更快,在大多數Ocaml, Haskell和F#的實現版本中標準就是原生支援用curried函式來實現多參函式的,那當然currying會帶來更高的效率……

valfirst_fixed_sorted3

=sorted3

1fun

rangeij

=ifi>jthen

elsei::

range(i+

1)jval

countup

=range

1fun

add_numbersxs=

zip(

countup

(length

xs))

xsdef

partial

(func,*

args,**

keywords

):def

newfunc(*

fargs,**

fkeywords

):newkeywords

=keywords

.copy

()newkeywords

.update

(fkeywords

)return

func(*

(args

+fargs

),**

newkeywords

)newfunc

.func

=func

newfunc

.args

=args

newfunc

.keywords

=keywords

return

newfunc

使用的例子:

>>> from functools import partial

>>> basetwo = partial(int, base=2)

>>> basetwo.__doc__ = 'Convert base 2 string to an int.'

>>> basetwo('10010')18

2樓:lambda喵

就是通過柯理化讓大家都變成了單參函式。

自然函式耦合變得easy了。

柯理化成立的基礎是函式語言的特性。

如果乙個函式可柯理化,那麼就可以偏運用。

偏應用返回高階函式,函式是一等公民所以可行。

在這裡你就可以看到函式式的魅力了。

程式設計變得很靈活。

3樓:

是基礎知識的事情,請接受這種表示方法

拿ocaml做例子吧,我記得ocaml和f#有些關係Ocaml中函式是及其引數是有型別檢查的,乙個函式let f : int -> int = fun a -> a + 1 ,即f(a)=a+1,從整數對映到整數

let add : int -> int -> int = fun a b -> a+b,兩個整數引數,對映到整數

let plus_one : int -> (int -> int) -> int = fun a f -> f a 第二個引數是函式

一層套一層的結構

如何理解 TCP IP, SPDY, WebSocket 三者之間的關係?

龍騰道默默地 TCP是基於IP IP是一種協議,不是IP位址 實現的,HTTP 1.1 SPDY WebSocket HTTP2.0是基於TCP實現的。IP 乙個底層網路定址協議。TCP 乙個相對可靠確保資訊送達 且按順序送達的中層資訊傳輸協議,效能相對於UDP較差。HTTP 1.1 上層網頁資訊傳...

如何理解 It make A one of Canada s most popular cities to live in ?

加拿大公共健康 這個語法有問題。It makes.A stands for a city s name. 首先,絕對是It makes.然後,回答題主的問題 1 正解 2 最高端要求有範圍的限定,所以平時一般看到的最高端都加定冠詞。但是Canada s已經是個範圍的限定,就不需要了,再舉幾個例子 o...

如何理解菩薩?

修行者 其實菩薩二字當做梵語 菩提薩埵 菩提是覺悟之意。什麼叫菩提?覺悟叫菩提。什麼叫覺悟?察見般若的道理叫覺悟,六識五蘊空寂無相,無相之相,得其妙有,叫做覺悟,找到自己的妙明真心而不著其所找,就叫覺悟。薩埵是有情,有情就是有情識 有生命的一切,不管是人 是蟲 是其他的眾生,扁毛或圓毛,或者看得到 ...