2010-02-18 68 views
10

不會把他們用他們所有的東西,我不太清楚所有的lambda表達式/塊可用於(除地圖/收集/辦/輕量級本地函數的語法)。如果有些人可以發表一些有趣但有些可以理解的例子(解釋)。對於實施例樂趣Lambda表達式

優選語言:蟒,Smalltalk的,Haskell的

回答

2

可以使功能性數據結構出lambda表達式。下面是一個簡單的 - 功能列表(蟒蛇),支持addcontains方法:

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值是。它也不是尾遞歸的,因爲一個好的功能結構應該是。練習給讀者!

+0

會改變它的工作? def contains(1st,item): return lst(item)or None – 2010-02-18 22:29:41

2

可以使用它們來控制數據流。例如,在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:我在上面說過關閉,我的意思是詞彙範圍關閉。這是詞彙範圍的關鍵,通常。

+0

你可以添加一個關於詞法範圍的描述嗎? – 2010-02-18 22:36:23

+0

@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

1

您可以使用lambda來創建一個Y組合,這是一個函數,它接受另一個函數,返回它的遞歸形式。這裏有一個例子:

def Y(le): 
    def _anon(cc): 
     return le(lambda x: cc(cc)(x)) 
    return _anon(_anon) 

這是一個想法棍棒值得一些更多的解釋,但不是吐出這裏看看this blog entry(上面的例子來自有太多)。

0

在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 
1

它的C#,但我個人感到很刺激的這篇文章我每次閱讀時間:

Building Data out of Thin Air - C#中Lisp的cons,car和cdr函數的實現。它演示瞭如何完全用lambda函數構建一個簡單的堆棧數據結構。

1

這是不是真的相當相同的概念在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)。