對於Haskell來說,我是全新的,所以如果問題很愚蠢,請大家道歉。遞歸狀態monad用於在構建列表時累積值?
我想要做的是遞歸建立一個列表,而在同一時間建立一個基於遞歸調用的累計值。這是我爲Coursera課程所做的一個問題,所以我不會發布確切的問題,但類似的東西。
例如說我想採取INTS的列表和雙每一個(忽略的例子的目的,我可以只使用map
),但我也想計數多少次數「 5'出現在列表中。
所以做了一倍我可以這樣做:
foo [] = []
foo (x:xs) = x * 2 : foo xs
到目前爲止那麼容易。但是我怎樣才能保持x
是五次的次數呢?我已經得到了最好的解決方法是使用顯式蓄能器這樣的,我不喜歡,因爲它顛倒了列表,所以你需要在最後做一個反向:
foo total acc [] = (total, reverse acc)
foo total acc (x:xs) = foo (if x == 5 then total + 1 else total) (x*2 : acc) xs
但我覺得這應該可以通過State
monad更好地處理,我之前沒有用過,但是當我嘗試構建一個適合我看到的模式的函數時,由於遞歸調用foo
而卡住了。有沒有更好的方法來做到這一點?
編輯:我需要這個工作很長的列表,所以任何遞歸調用也需要尾遞歸。 (由於Haskell的'tail recursion modulo cons',我在這裏的例子設法是尾遞歸的)。
相關的問題: 「尾巴優化保障 - 在Haskell循環編碼」(http://stackoverflow.com/q/9149183/ 849891)。 –
您的示例尾遞歸在什麼意義上?我認爲它積聚了沉重,並導致「內存泄漏」。甚至簡單地調用'reverse'似乎足以導致內存泄漏。 – yairchu
當我說*它是*尾遞歸時,我的意思是簡單的地圖示例,而不是第二個代碼片段。 TBH我很難確定什麼是Haskell中的高效代碼,它看起來和我用過的其他語言完全不同。認爲我需要做更多的閱讀:-) – Russell