2011-03-18 27 views
2

對不起,模糊的標題,我想我只是不明白我的問題,足以問問它,但在這裏。我想寫一個遞歸函數,它需要一系列函數來評估,然後用他們的結果&等等來調用它自己。遞歸在某個返回數字的函數處停止。lazy-seq爲遞歸函數

但是,我希望函數在遞歸中的任何一點被評估爲f,它被包裝在一個函數s中,該函數返回一個初始值(比如0,或者另一個函數i的結果)評估時間,然後評估f的結果(以便下次評估時返回先前評估的結果,並計算下一個值)。目標是解耦遞歸,以便它可以繼續而不會導致this

我想我要求一個懶惰的seq。這是一個充滿了一端功能評估的管道,歷史結果從另一端出來。

回答

0

我不明白你的整個目標:你使用的很多術語都是模糊的。就像,你想要評估一系列函數然後重複他們的結果是什麼意思?這些函數必須是無參數函數(thunk),那麼,我想呢?但有一個thunk首先返回x,然後在你下次調用它時返回y,這是相當邪惡和有狀態的。也許trampoline將解決你的問題的一部分?

你也鏈接到你想避免的東西,但似乎粘貼了錯誤的鏈接 - 它只是一個鏈接回到這個頁面。如果你想避免堆棧溢出,那麼蹦牀很可能是一個好方法,儘管循環/重複應該是可能的。除非返回y,否則thunk返回x的這個概念是瘋狂,如果避免堆棧溢出是您的主要目標。不要那樣做。

我已經先行一步,在你可能有最合理的最終目標邁出了猜測,這是我的實現:

(defn call-until-number [& fs] 
    (let [numeric (fn [x] (when (number? x) x))] 
    (loop [fs fs] 
     (let [result (map #(%) fs)] 
     (or (some numeric result) 
      (recur result)))))) 

(call-until-number (fn [] (fn [] 1))) ; yields 1 
(call-until-number (fn [] (fn [] 1)) ; yields 2 
        (fn [] 2)) 
(call-until-number (fn f [] f)) ; never returns, no overflow 
+0

謝謝你們,看起來像蹦牀可能是我需要的東西 – gone 2011-03-21 05:58:01

3

你的描述讓我想起了一些reductions?減少將執行減少並返回所有中間結果。

user> (reductions + (range 10)) 
(0 1 3 6 10 15 21 28 36 45) 

這裏(範圍10)創建的0到9的減少一個SEQ適用+反覆,傳遞+的先前結果和所述序列中的下一個項目。所有的中間結果都會返回。您可能會發現看看減少的source是有益的。

如果您需要爲此構建一個測試(檢查值),那麼在您的函數中使用if會很容易(儘管它不會停止遍歷seq)。如果你想在條件成立的情況下提前退出,那麼你需要編寫自己的循環/重複,而amalloy已經做得很好。

我討厭這麼說,但我懷疑這也可能是Monad的情況,但IANAMG(我不是Monad Guy)。