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?
Thanks
CodePudding user response:
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 Num
bers:
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 element, 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]