簡體   English   中英

功能組成

[英]Composition of Functions

def thrice(f):
    return lambda x: f(f(f(x)))
print(thrice(thrice)(lambda x: x+3)(2))
print((thrice)(thrice)(lambda x: x+3)(2))

兩個打印語句都給出了答案83,但是我不明白答案是如何得出的。 有人能啟發我兩者之間的區別嗎?

兩者之間唯一的區別是一對毫無意義的括號,因此它們當然給出相同的答案。 與要求兩者之間的區別相同:

math.abs(2)
(math.abs)(2)

或者,甚至更好(感謝OlivierMelançon指出這一點),兩者之間的區別:

1 + 2
(1) + 2

實際上,沒有區別。 解析它們的第一步有所不同,但是它們最終具有相同的AST,因此具有相同的字節碼,因此具有相同的行為。


您可能想問一下這個問題:

>>> thrice(thrice(lambda x: x+3))(2)
29
>>> thrice(thrice)(lambda x: x+3)(2)
83

那是很大的不同。

在第一個中,我們在lambda上調用thrice ,因此它給我們提供了一個函數,該函數將3加,然后加3,然后加3,所以它加9。然后我們在其上調用thrice ,因此給我們一個加9的函數,然后加9的函數,再加9的函數,所以加27的函數。然后在2上調用它,當然得到29。

在第二個函數中,我們在thrice上調用thrice,因此它為我們提供了一個功能,該函數可以將thrice thrice ,執行我們要求它執行3 ** 3(27)次的任何操作。 然后,我們在lambda上調用它,因此它加了3到37次,這意味着它加了81。然后在2上調用它,得到83。

如果將thricethrice(thrice)應用於lambda x: x+1而不是lambda x: x+3 ,則可能不會造成混淆,因此您不會混淆那些單獨的3,並且在0上調用final函數而不是2。


對於大多數功能,您不能通過編寫類似的代碼來混淆自己—一個版本或另一個版本將是一個簡單的TypeError (嘗試編寫math.fabs(math.fabs)int(int)看看會發生什么。)是什么讓thrice如此特別?

好吧,考慮thrice的類型。 您給它提供類型A->A任何函數(也就是說,它接受某個類型A的值並返回相同類型A的值),並且它返回另一個類型A->A函數。 但這意味着它本身就是A->A類型的函數,因此您可以對其進行調用。 在您考慮類型之前,這似乎是令人難以置信的事情之一,但是一旦您做完,這並沒有什么令人興奮的。 “不,約翰,你是類型理論!” 然后約翰是Haskell。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM