使用累加器的Haskell递归

use*_*032 2 recursion haskell function accumulator

对于我想要实现的解算器,我正在尝试创建一个函数,该函数将查找给定列表的3个相同且相邻的数字.然后,如果有3个相同且相邻的数字,则将第1个和第3个相同的数字标记为"0",并将中间值设置为负数.

我想知道为什么这给了我一个错误:

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)
Run Code Online (Sandbox Code Playgroud)

app*_*ive 8

既然acc是一个列表,我们不想[acc]在第一个守卫中返回chnge,而只是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])
Run Code Online (Sandbox Code Playgroud)

这看起来有点偏,但真正的问题是'模式匹配'的缺乏和危险的使用head,tail!!.尝试更像这样的东西,也许吧?(虽然它不使用累加器):

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]
Run Code Online (Sandbox Code Playgroud)

连续三个的情况可以被认为是一种模式,因此我们在它们相等时做出特殊情况.