[英]What's the point of lambda in scheme?
我正在學習計划。 我知道如何使用lambda和let表達式。
然而,我正在努力弄清楚使用lambda的重點是什么。 你不能用lambda做你能做的一切嗎?
看一個lambda表達式是比let更好的選擇的例子會特別有用。
還有一件事 - 是否還有讓let比lambda更有用的情況? 如果是這樣的例子也會很好。
編輯:我也對對比定義和lambda感興趣,因為它們似乎執行類似的任務。
感謝大家的幫助。 在閱讀了你的答案之后,我做了一些更多的研究lambda / let / define,現在對它的了解要好得多。
我遇到了一個很酷的lambda用法的好例子 - 從程序中返回匿名函數。 例如,下面的過程operateTwice
返回一個匿名函數,該函數基於傳入過程的參數:
(define operateTwice
(lambda (op1 op2)
(lambda (x y)
(op2 (op1 x y) y))))
((operateTwice * +) 2 3) ;equivalent to: (+ (* 2 3) 3), or in standard notation 2*3+3
輸出:
9
一個let
是一個lambda
。
例如
(let ((x 1))
body)
可以翻譯成
((lambda (x) body) 1)
此外,在Scheme中, 所有控制和環境結構都可以由lambda表達式和lambdas的應用程序表示。
因此, lambda
比let
更強大,並且構成了Scheme中許多有趣結構的基礎。
關於define
和lambda
,頂級define
會向頂級環境添加綁定。
當你寫作
(define (f x)
body)
你真的在說
(define f (lambda (x) body))
嵌套定義被轉換為letrec
,也可以使用lambdas重寫。
所以,同樣,很多Scheme構造可以使用lambda
轉換成某些東西,因此你很了解lambda
是非常值得的。
如果要創建一個函數將其用作另一個函數的參數(例如map
),則使用lambda
,但實際上並不想命名該函數。
例如,如果要為列表中的每個數字添加42,則可以執行以下操作:
(define (add42 x) (+ x 42))
(map add42 (list 1 2 3 4))
但是如果你不想給你只使用一次的函數命名,你可以這樣做:
(map (lambda (x) (+ x 42)) (list 1 2 3 4))
實際上,它只是Lambda表達式的簡寫。 以下兩個表達式是等效的:
(let ((alpha 7)) (* 5 alpha))
((lambda (alpha) (* 5 alpha)) 7)
Lambda遵循語言的哲學,即一切都應該看起來像一個數學函數。 但在實踐中,如果變量太多,讓我們更容易弄清楚發生了什么。 想象一下10個變量,它們的值在Lambda塊之后定義,並且你試圖將每個變量與變量名稱相匹配,讓變量值放在它們的名稱旁邊,方便程序員使用,但更少符合功能編程理念。
Lambda可用於從更高階函數返回函數,但是不能這樣做。 例如:
(define (plus-list x)
(cond ((number? x)
(lambda (y) (+ (sum-n x) y)))
((list? x)
(lambda (y) (+ (sum-list x) y)))
(else (lambda (x) x))
))
> ((plus-list 3) 4)
10
> ((plus-list '(1 3 5)) 5)
14
> ((plus-list 'a) 5)
5
Lambda還可用於將函數傳遞給函數:
>(map (lambda (x) (+ 1 x)) '(-1 2 -3))
(0 3 -2)
lambda創建新的匿名函數,當然每次使用它們時都會對它們進行評估。
讓我們為值創建臨時名稱,並設置一次以便在let表單定義的范圍內使用。
他們真的是非常不同的野獸。
一些例子 :
(lambda(x)(* 5 x))
(let([x 2])(* 5 x))10(let([f(lambda(x)(* 5 x))])(f 2))10
first form創建一個乘以5的函數
第二種形式將2分配給x並將其乘以5得到10
第三,我們使用1的函數(多數為5)並將其作為參數調用2,結果也是10
在Scheme中,過程(或函數)是第一類對象,如列表,數字或字符串。 要創建列表文字,請使用名為list
的原語:
> (define marks (list 33 40 56))
> marks
> (33 40 56)
就像這樣,要創建一個過程,可以使用lambda
原語(或特殊形式):
> (define add-marks (lambda (m) (apply + m)))
> (add-marks marks)
> 129
由於過程是抽象的主要形式,Scheme為define
提供了一個快捷方式 , define
輕松綁定新過程:
> (define (add-marks m) (apply + m))
除此之外,過程就像所有其他第一類對象一樣。 它們可以作為參數傳遞給其他過程,並且過程可以評估以生成(或返回)另一個過程。
你可以這樣認為......你創建了一個使用另一個函數的函數,但是你想讓事情更加模塊化,所以你要做的就是把第二個函數作為第一個函數的參數調用,這樣你就有可能每當你覺得你需要另一種功能時改變第二種......希望這是有道理的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.