2012-10-04 83 views
2

我試圖做一個函數,它會查找給定列表的3個相同和相鄰的數字,對於我試圖實現的求解器。然後,如果有3個相同和相鄰的數字,它會將第一個和第三個相同的數字標記爲「0」,並將中間值設置爲負數。使用累加器的Haskell遞歸

我很奇怪,爲什麼這是給我一個錯誤:

change xs = chnge xs [] 
    where 
    chnge xs acc 
     | length xs <= 2 = [acc] 
     | (head xs == xs !! 1) && (head xs == xs !! 2) = [0, (xs !! 1)*(-1), 0] ++ tail xs 
     | otherwise = chnge (tail xs) (acC++ head xs) 
+0

這只是一個解析錯誤,因爲與定義'change'的子句相比,where子句(以及它的內容)應該縮進至少一個空格。作爲一般規則,您應該在您的問題中包含GHC給您的錯誤消息。 – macron

+0

對不起,那是我的錯。我只是忘了縮進其餘的代碼。我已經修復它以匹配它的真實性。 – user1670032

+1

解析錯誤是由於stackoverflow弄亂了格式,而不是原始來源。 –

回答

8

由於acc是一個列表,我們不希望在chnge第一後衛回[acc],只是acc;同樣在otherwise行你不想acC++ head xs這意味着xs是列表的列表 - 它的第一個成員怎麼可以追加?相反acC++ [head xs]所以也許:

change xs = chnge xs [] where 
    chnge xs acc 
     | length xs <= 2 = acc 
     | (head xs == xs !! 1) && (head xs == xs !! 2) = [0, (xs !! 1)*(-1), 0] ++ tail xs 
     | otherwise = chnge (tail xs) (acC++ [head xs]) 

這似乎有點過,但真正的問題是「模式匹配」和危險的使用headtail!!的缺乏。試試更像這樣的,也許吧? (它不使用雖然累加器):

change []  = [] 
change [x] = [x] 
change [x,y] = [x,y] 
change (x:y:z:ws) | x == y && y == z = 0 : (-y) : 0 : change ws 
change (x:xs) = x : change xs 

-- *Main> change [12,12,66,66,66,44,44,99,99,99,76,1] 
-- [12,12,0,-66,0,44,44,0,-99,0,76,1] 

三連勝的情況下,可以被看作是一個模式,使我們作出時,他們等於一個特例。