Jordan
Jordan

Reputation: 35

Haskell adding an element to a list via recursion

I'm attempting to understand lists in Haskell and I've ran into something i'm unsure on. Is it possible to iterate through a loop and on each iteration add an item to a list ? for the purpose of the question i wrote the following code:

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

I thought that this would work but it seems to give the error "Couldn't match type ‘[]’ with ‘IO’". I'm not quite sure why this error is coming up as there is no input or output being asked for from the user. I thought it may have been to do with the "print n" but it doesn't seem to work without that line.

Cheers in advance for any help

Upvotes: 0

Views: 1503

Answers (1)

randomusername
randomusername

Reputation: 8105

This will not do what you think it does, in Haskell everything is immutable (once it has been given a value, that value cannot change). What you might be trying to do is:

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

Then in the interpreter you'll get

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

Pay careful attention to the signature of addNumbers, it accepts an Int and returns a list of Int's encapsulated by the IO monad. It has to be encapsulated by the IO monad because the call to print returns () in the IO monad and without that then the value won't be printed.

If you just want a list of Int's prepended to a list then you can easily do

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

Upvotes: 4

Related Questions