1
votes

I am trying to learn haskell at the moment and I've come across an example problem that I'm having trouble with.

The problem is that imagine we has lists representing numbers, for example the number 12 is [2,1] and 148 is [8,4,1], then how do we add these two lists together as if they were numbers. My intuition is we carry numbers with they add to over 10 similar to how addition is done with large numbers.

My code so far is:

addLnat [x] [y] = rem  (x + y) 10 : (quot (x + y) 10) : []          
addLnat (x:xs) (y:ys) =  (rem  (x + y) 10) : w + head (addLnat xs ys)
                            where w = quot (x + y) 10

However this will not compile and I don't really understand why to me this seems like the solution, For example:

If we start with [3,2,1] and [6,6,9]. We add the 6 and 3 and the quotient is 0 so 9:0+ and repeat until we get to the final case.

Any ideas on why this is not working/compiling?

1
Here there's another implementation you can look at. - Shoe
@Jefffrey take 1 is a total alternative for head, and drop 1 for tail, so that headOr 0 = sum . take 1 and tailOr [] = drop 1. - Will Ness
I agree with tailOr [] == drop 1. But not take 1 being in any way equal to headOr. In any case both tailOr and headOr are more general in the possible set of return values. - Shoe

1 Answers

2
votes
(rem  (x + y) 10) : w + head (addLnat xs ys)

The cons : operator requires a list on its right side. You probably meant

(rem  (x + y) 10) : w + head (addLnat xs ys) : tail (addLnat xs ys)

Be careful that this will lead to horrible performance, since you are making two recursive calls, which cause an exponential blowup.

More significantly, even neglecting performance, the above looks wrong, since w + ... might overflow 10. Think about adding 1 to 9999: you need to achieve the cascading effect.

Try to rework your function so that it takes an additional carry argument.