不會把他們用他們所有的東西,我不太清楚所有的lambda表達式/塊可用於(除地圖/收集/辦/輕量級本地函數的語法)。如果有些人可以發表一些有趣但有些可以理解的例子(解釋)。對於實施例樂趣Lambda表達式
優選語言:蟒,Smalltalk的,Haskell的
不會把他們用他們所有的東西,我不太清楚所有的lambda表達式/塊可用於(除地圖/收集/辦/輕量級本地函數的語法)。如果有些人可以發表一些有趣但有些可以理解的例子(解釋)。對於實施例樂趣Lambda表達式
優選語言:蟒,Smalltalk的,Haskell的
可以使功能性數據結構出lambda表達式。下面是一個簡單的 - 功能列表(蟒蛇),支持add
和contains
方法:
empty = lambda x : None
def add(lst, item) :
return lambda x : x == item or lst(x)
def contains(lst, item) :
return lst(item) or False
我只是編碼這個快速的樂趣 - 請注意,你不允許添加任何falsy值是。它也不是尾遞歸的,因爲一個好的功能結構應該是。練習給讀者!
可以使用它們來控制數據流。例如,在Smalltalk中,「ifTrue:ifFalse:」方法是布爾對象的一種方法,在每個True和False類上都有不同的實現。表達
someBoolean ifTrue: [self doSomething] ifFalse: [self doSomethingElse]
使用兩個封閉件---塊,在Smalltalk語法---一個用於真實分支,和一個用於假分支[方括號]。執行「:ifFalse:ifTrue」類真實的情況是
ifTrue: block1 ifFalse: block2
^block1 value
和類錯誤:
ifTrue: block1 ifFalse: block2
^block2 value
瓶蓋,在這裏,用於延緩評價,這樣一個關於控制流的決定可以採取,沒有任何專門的語法(除塊的語法)。
Haskell是有一點不同,其懶惰的評價模型有效自動關閉生產在許多情況下的效果,但在計劃你最終使用控制lambda表達式流很多。例如,這裏是一個實用程序來檢索關聯列表的值,供給的情況下的可選計算的默認其中值不存在:
(define (assq/default key lst default-thunk)
(cond
((null? lst) (default-thunk)) ;; actually invoke the default-value-producer
((eq? (caar lst) key) (car lst))
(else (assq/default key (cdr lst) default-thunk))))
這將被稱爲像這樣:
(assq/default 'mykey my-alist (lambda() (+ 3 4 5)))
這裏的關鍵是使用拉姆達的延遲默認值的計算,直到它實際上是已知的要求。
又見延續傳遞風格,這需要此發揮到了極致。例如,Javascript依靠延續傳遞式和閉包來執行所有的阻塞操作(如睡眠,I/O等)。
ETA:我在上面說過關閉,我的意思是詞彙範圍關閉。這是詞彙範圍的關鍵,通常。
你可以添加一個關於詞法範圍的描述嗎? – 2010-02-18 22:36:23
@Roman:詞法範圍意味着如果你有一個像'f:= a - >(x - >(a ++)* x)'這樣的函數,調用'f(2)'將返回函數'x - >(a ++)* x'將'a'綁定到一個值爲2的變量。因爲那是函數在詞彙意義上定義範圍的'a'。然而,這個'a'完全獨立於'f(3)'或另一個'f(2)'調用返回的函數中的'a',因爲每個調用都會創建一個新的閉包。 – 2010-03-01 08:46:04
您可以使用lambda來創建一個Y組合,這是一個函數,它接受另一個函數,返回它的遞歸形式。這裏有一個例子:
def Y(le):
def _anon(cc):
return le(lambda x: cc(cc)(x))
return _anon(_anon)
這是一個想法棍棒值得一些更多的解釋,但不是吐出這裏看看this blog entry(上面的例子來自有太多)。
在Haskell的例子來計算單個variabled函數的導數使用數值近似:
deriv f = \x -> (f (x + d) - f x)/d
where
d = 0.00001
f x = x^2
f' = deriv f -- roughly equal to f' x = 2 * x
它的C#,但我個人感到很刺激的這篇文章我每次閱讀時間:
Building Data out of Thin Air - C#中Lisp的cons,car和cdr函數的實現。它演示瞭如何完全用lambda函數構建一個簡單的堆棧數據結構。
這是不是真的相當相同的概念在Haskell等,但在C#,拉姆達構建體具有(任選地)來編譯到一個objcet模型表示碼(表達式樹)的能力,而而不是代碼本身(這本身就是LINQ的基石之一)。
這反過來會導致一些非常富有表現力的元編程的機會,例如(其中這裏的拉姆達是表達「給出一個服務,你想用它做什麼?」):
var client = new Client<ISomeService>();
string captured = "to show a closure";
var result = client.Invoke(
svc => svc.SomeMethodDefinedOnTheService(123, captured)
);
(假設一個合適的Invoke
簽名)
這種類型的東西有很多用途,但我用它來構建RPC堆棧,不需要任何運行時代碼生成 - 它只是解析表達式 - 樹,找出調用者的意圖,將其翻譯爲RPC,調用它,收集響應等(討論更多here)。
會改變它的工作? def contains(1st,item): return lst(item)or None – 2010-02-18 22:29:41