2010-03-12 63 views
4

我試圖找出如何在方案程序沒有使用頂級ifcond類似的構造做「早期返回」。方案提前「短路迴歸」?

(define (win b) 
(let* ((test (first (first b))) 
     (result (every (lambda (i) (= (list-ref (list-ref b i) i) test)) 
         (enumerate (length b))))) 
    (when (and (not (= test 0)) result) test)) 
0) 

例如,在上面的代碼,我想win返回test如果when條件得到滿足,否則返回0。但是,什麼情況是,該過程將總是返回0,無論when條件的結果。

我構建我的代碼,這種方式是因爲在此過程中,我需要做的(類似於例如let*多個塊)衆多複雜的檢查,並把一切都在一個大cond會很笨重的原因。

+1

是的,但如果你犯了一個很大的COND,把讓每塊在一個單獨的 功能與精心挑選的名字,你會風與更好,更可讀的代碼。 – 2010-03-15 04:21:23

回答

7

這裏是如何使用的呼叫/ cc的建立return自己。

(define (example x) 
    (call/cc (lambda (return) 
    (when (< x 0) (return #f)) 
    ; more code, including possible more calls to return 
    0))) 

一些方案定義了一個名爲/出租宏觀CC,可以讓你放下一些拉姆達的噪音:

(define (example x) 
    (let/cc return 
    (when (< x 0) (return #f)) 
    0)) 

當然,如果你的計劃沒有,就讓/ CC是微不足道的寫。


這是可行的,因爲call/cc保存了被稱爲延續的點。它將該延續傳遞給它的函數參數。當函數調用該延續時,Scheme放棄迄今爲止建立的任何調用堆棧,並從調用/ cc調用結束時繼續。當然,如果函數從不調用continuation,那麼它只是正常返回。

延續沒有得到真正的心靈彎曲,直到你開始從該函數返回他們,也許將它們存儲在全局數據結構,後來打電話給他們。否則,它們就像任何其他語言的結構化轉換語句(while/for/break/return/continue/exceptions/conditions)。


我不知道你完整的代碼是什麼樣子,但它可能是更好的去與COND並分解出複雜的支票兌換成獨立的功能。需要returnlet*通常是過於緊迫的代碼的症狀。然而,調用/ cc方法應該讓你的代碼現在工作。

+0

感謝您的解釋。正如你所建議的那樣,我最終使用了一個頂級cond,並創建了單獨的函數。 – Suan 2010-03-12 18:47:37

1

的一種方法是使用遞歸代替循環,然後早早出局是不是進一步遞歸實現。

0

您可以使用「帶有當前繼續的呼叫」支持來模擬回報。在wikipedia上有一個例子。該功能被稱爲呼叫與電流延續,雖然有經常是一個別名叫做呼叫/立方厘米這是完全一樣的東西。還有一個稍微乾淨例子here

注:這是一個相當高級的計劃編程技術,可以是一個有點頭腦在第一彎...... !!!!

0

在這種情況下,你如果想要一個,雖然不是頂級,你不想。

(define (win b) 
    (let* ((test (first (first b))) 
     (result (every (lambda (i) (= (list-ref (list-ref b i) i) test)) 
         (enumerate (length b))))) 
    (if (and (not (= test 0)) result) 
     test 
     0))) 

它總是返回零的原因是,是否執行時的主體,其結果將被丟棄在地板上。你看,拉姆達在功能隱含定義表單創建一個隱含開始塊太多,所以

(define foo 
    (lambda (b) 
    (begin 
     (let ...) 
     0))) 

和方式開始工作原理是,它返回裏面的最後形式的結果,同時刪除所有的中間結果地上。這些中間結果有意造成副作用。你沒有使用任何這些,這很好(!),但是你必須小心在函數定義中只有一種形式(其結果你真的想要)。

GREM

+0

是的。在Scheme中,如果在(lambda()stmt1 stmt2 stmt3)中有多個表達式,則只返回最後一條語句的結果。在提問者的例子中,如果在最後有一個if語句會起作用,那麼continuation可能是過度的。 – erjiang 2010-03-14 22:01:33