Concatenating 2 inputted lists in Haskell

I’m trying to combine 2 lists from input but I am getting an error every time.
Here is my code:

myAppend :: [a] -> [a] -> [a]
myAppend a b = zipWith (+) a b

Getting this error:
"No instance for (Num a) arising from a use of ‘+’"

I was given this solution but it doesn’t really make sense to me

myAppend :: [a] -> [a] -> [a]
myAppend [] xs = xs
myAppend (y:ys) xs = y:(myAppend ys xs)

I don’t really understand the second and third line.

Can anyone help?


>Solution :

Your myAppend does not concatenate two lists, it aims to sum elementwise the two lists, so myAppend [1,4,2,5] [1,3,0,2] will produce [2,7,2,7]. It will require a Num a constraint, since it can only work if the elements of the lists are Numbers:

myAppend :: Num a => [a] -> [a] -> [a]
myAppend a b = zipWith (+) a b

As for the solution here it uses recursion. Lists in Haskell are like linked lists: you have a an empty list ("nil") which is represented by the [] data constructor, and a node ("cons") which is represented with (x:xs) where x points to the first item, and xs points to the list of remaining elements. So [1,4,2,5] is short for (1:(4:(2:(5:[])))).

If we want to append [1,4] and [2,5] we thus want to produce a list (1:(4:(2:(5:[])))) out of (1:(4:[])) and (2:5:[]). This means we create a linked list with all the elements of the first list, but instead of pointing to the empty list [], we let it point to the second list for the remaining elements. We do this through recursion:

myAppend (y:ys) xs = y : myAppend ys xs

will match if the first list unifies with the (y:ys) pattern. In that case we thus produce a list with y as first elemnent, and the result of myAppend ys xs as as list of remaining elements ("tail"). Eventually we will thus call myAppend ys xs with the empty list [] as first item. In that case, we thus return the second list instead of the empty list, to append the second list to it.

We thus make calls that look like:

   myAppend [1, 4]     [2, 5]
=  myAppend (1:(4:[])) (2:(5:[]))
-> 1 : (myAppend (4:[]) (2:(5:[])))
-> 1 : (4 : (myAppend [] (2:(5:[]))))
-> 1 : (4 : (2:(5:[]))
=  [1, 4, 2, 5]

Leave a Reply