Haskell:在遵循递归函数时,我似乎无法将任何东西链接到我的累加器 - 谁能解释一下我在这里错了哪里?

Haskell: I seem to not be able to link anything to my accumulator in following recursive function - can anyone explain where I am wrong here?

提问人:Tay 提问时间:6/26/2023 最后编辑:Tay 更新时间:6/26/2023 访问量:64

问:

任务: “定义一个函数'start',该函数返回给定列表的所有元素,但最后一个元素除外”

我的解决方案:

start list = start' list []
    where
        start' (x:[]) acc = acc
        start' (x:xs) acc = start' xs (acc:x)

在尝试编译时,ghc 似乎抛出了一个错误,因为第 4 行的最后一个表达式位于 '(acc:x)'。 有人可以解释一下,为什么会这样吗? 我真的不在乎这是否是解决这个问题的最有效方法——我只想找到我错的地方。

多谢。

列表 功能 哈斯克尔 递归 链接列表

评论

0赞 Robin Zigmond 6/26/2023
提示:哪个 AND 是列表,哪个是单个元素?xacc

答:

3赞 willeM_ Van Onsem 6/26/2023 #1

(acc:x)没有多大意义:是一个列表,是一个元素。 获取一个项目和一个列表,并构造一个列表,其中项目是第一个项目,给定列表是结果中其余项目的列表。accx(:) :: a -> [a] -> [a]

您可以在右端附加:

start list = start' list []
  where
    start' (x : []) acc = acc
    start' (x : xs) acc = start' xs (acc ++ [x])

你在这里基本上做了 init :: [a] -> [a] 所做的,除了你的版本也适用于空列表。startstart

然而,使用累加器不是必需的,只会增加计算工作量和内存使用量。您可以使用:

start :: [a] -> [a]
start [] = []
start (x : xs) = go xs x
  where
    go [] _ = []
    go (x : xs) y = y : go xs x

或更短:

start :: [a] -> [a]
start [] = []
start (x : xs) = go xs x
  where
    go [] = const []
    go (x : xs) = (: go xs x)

这也允许使用无限列表,其中永远不会停止,但只需要有限的内存量。start