Haskell通过递归向列表添加元素

时间:2015-01-05 00:20:44

标签: haskell ghci

我正在尝试理解Haskell中的列表,我遇到了一些我不确定的事情。是否可以迭代循环并在每次迭代时将项添加到列表中?为了问题的目的,我写了下面的代码:

list = []
addNumbers 0 = return ()
addNumbers n =
 do
    print n
    n : list
    addNumbers (n-1)

我认为这会起作用,但它似乎给出错误“无法匹配类型'[]'和'IO'”。我不太清楚为什么会出现这个错误,因为用户没有要求输入或输出。我认为它可能与“打印n”有关,但如果没有那条线似乎没有用。

提前为任何帮助干杯

1 个答案:

答案 0 :(得分:4)

这不会做你认为它做的事情,在Haskell中一切都是不可变的(一旦给出了一个值,那个值就不会改变)。你可能想要做的是:

addNumbers :: Int -> IO [Int]
addNumbers 0 = return []
addNumbers n = do print n
                  ns <- addNumbers (n-1)
                  return (n:ns)

然后在翻译中你会得到

ghci> addNumbers 3
3
2
1
[3, 2, 1]
ghci>

请注意addNumbers的签名,它接受Int并返回由IO monad封装的Int列表。它必须由IO monad封装,因为打印调用在IO monad中返回(),如果没有,则不会打印该值。

如果您只想在列表中添加Int列表,那么您可以轻松完成

foo 0 = [0]
foo n = n:foo (n-1)