2016-03-17 42 views
1

任務是使用foldrfoldl只使用一個傳遞。 我用這個決定:獲取位於初始列表偶數位置的元素列表

evenOnly = fst . foldr (\x (y1, y2) -> (y2, x:y1)) ([],[]) 

爲有限名單還不錯。如果我嘗試evenOnly [1,2..]我會失敗。我知道這是因爲暫停的caclulations,但我怎樣才能拆分列表或如何將列表位置或其他信息傳遞給列表末尾的計算?

+0

foldr'工作在[與無限列表與foldl與foldr相似的行爲(http://stackoverflow.com/questions/3082324/foldl-versus-foldr-behavior-with-infinite-lists) – Bakuriu

+0

好了,'的可能的複製無限列表**提供了**它正在使用的函數足夠懶惰。在[這個答案]中明確解釋(http://stackoverflow.com/a/3085516/510937)。 Quote:「**如果**'f'在第二個參數 - 數據構造函數中是惰性的 - 例如 - 結果將漸進式地延遲,摺疊的每一步只在需要的結果的一部分它被評估。「你使用的函數總是使用它的第二個參數,所以它的行爲「像'foldl'」。 – Bakuriu

+0

當然。我不是說這是'foldr'唯一可能的解決方案。無論如何,目前無法發明更先進的東西。 – BarbedWire

回答

2

您可以使用lazy pattern~(x1, y2)

> let evenOnly = fst . foldr (\x ~(y1, y2) -> (y2, x:y1)) ([],[]) 
> take 20 $ evenOnly [1..] 
[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40] 

這是基本相同

> let evenOnly = fst . foldr (\x y -> (snd y, x:fst y)) ([],[]) 

其中有迫使對構造太早的優勢。也就是說,上面的lambda將在其的輸出之前產生(,)構造函數,其輸出它要求y(「遞歸」結果)。

+0

謝謝!你讓我很快樂。 – BarbedWire

相關問題