2012-11-27 32 views
0

最近我試圖解決使用Foldr的問題。任務如下:Foldr應用程序

In:[5,1,3,8,2,4,7,1] 
Out:[16,8] 

這意味着,我會加倍那些在奇數索引位置甚至數位的輸入列表元素。我寫的程序,而無需使用這是繼foldr相似:(它顯示模式匹配失敗:頭[])

findPos list elt = 
    map fst $ filter ((elt==).snd) $ zip [0..] list 

doublePos [] = [] 
doublePos (x:xs) 
    | ((head(findPos xs x)`mod` 2) /= 0) && (x `mod` 2 == 0) = 
     [2*x] ++ doublePos xs 
    | otherwise = doublePos xs 

我怎樣寫用foldr這個計劃?

+1

這是一個奇怪的任務......這不是作業,對不對?嚴重的是,用'foldr'來做這件事只會讓它變得無法理解而沒有任何好處。我只是一步一步地做到這一點:刪除偶數索引的元素,刪除奇數條目,將剩餘值加倍,完成。 '地圖(* 2)。甚至過濾。 remAtEvenPos'' where remAtEvenPos(a:b:l)= a:l; remAtEvenPos l = l'。這就是慣用的Haskell解決方案。 – leftaroundabout

+0

@leftaroundabout thnx您的建議。但作爲初學者,我嘗試使用foldr來解決問題。 – sabu

+1

@leftaroundabout,你的意思是'remAtEvenPos(a:_:l)= a:remAtEvenPos l'? – huon

回答

5

foldr對於這個函數並不是一個好的選擇,因爲你需要從列表的前面傳遞每個元素索引的奇偶性。

列表解析也許是最簡潔:

doublePos xs = [2*x | (i,x) <- zip [0..] xs, even x, odd i] 

或者你可以使用普通的舊遞歸:由具有蓄電池

doublePos' (_:x:xs) 
    | even x = (2*x) : doublePos' xs 
    | otherwise =   doublePos' xs 
doublePos' _ = [] 

不過,如果你必須使用foldr,你可以做到這一點是一個函數 ,它以當前索引的奇偶校驗爲參數:

doublePos'' xs = foldr step (const []) xs False where 
    step x next p 
    | p && even x = 2*x : next (not p) 
    | otherwise = next (not p) 
+0

thanx很多。使用foldr的最終實現對我來說是位高級別。但我得到了遞歸解決方案。非常感謝 – sabu

+0

@SaugataBose:是的,累積一個函數有點奇怪,我不建議在有其他選項可用時編寫這樣的代碼。 – hammar

2

爲什麼您現有的代碼會導致模式匹配失敗:doublePos [5,1,3,8,2,4,7,1]x = 5xs = [1,3,8,2,4,7,1]匹配第二個等式。這會導致對head (findPos [1,3,8,2,4,7,1] 5)進行評估,但這會降低至head [],並且會出現錯誤。

要展開此操作:您似乎希望從findPos中獲得的內容是當前元素的索引,相對於原始列表的開頭。但是實際得到的結果是當前元素下一次出現的索引,相對於下一個元素......並且如果它不再出現,則會出現錯誤。

(使用字符作爲此列表中的元素,以避免列表索引和列表元素之間的混淆。)

0 1 2 3 4 5 6 7 8 9 10  <-- indices relative to start 
'H':'e':'l':'l':'o':' ':'t':'h':'e':'r':'e':[] <-- original list 
    |   | 
x = 'e'   |    V     say we're here 
    xs = 'l':'l':'o':' ':'t':'h':'e':'r':'e':[]  head (findPos xs x) = 6 but we wanted 1 
       |    ^
      x = 'o'        say we're here instead 
       xs = ' ':'t':'h':'e':'r':'e':[]  head (findPos xs x) = error "head []" but we wanted 4 

這可以在唯一的辦法可能是工作,如果你傳遞原始列表findPos。但是,您唯一可用的列表是尚未遞歸的原始列表的一部分。無論如何,從哈馬爾的回答可以看出,這樣做有更好的方法。