2012-10-04 118 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] 

三连胜的情况下,可以被看作是一个模式,使我们作出时,他们等于一个特例。