Reputation: 1080
I am learning Haskell and i try to write a code which somehow zips two lists. MY code should return me these list in these inputs
Inputs:
[1,2,3] [6,5,4]
[1,2,3] [6,5]
[1,2] [6,5,4]
outputs:
[(1,6),(2,5),(3,4)]
[(1,6),(2,5),(3,3)]
[(1,6),(2,5),(4,4)]
My code is this
zip' :: (Integral i, Integral b) => [i] -> [b] -> [(i,b)]
zip' [][] = []
zip' (x:xs)[] = bmi x : zip' xs []
where bmi x = (x,x)
zip' [](x:xs) = bmi x : zip' [] xs
where bmi x = (x,x)
zip' (x:xs) (y:ys) = bmi x y : zip' xs ys
where bmi x y = (x,y)
I am looking forward for your responces
Upvotes: 2
Views: 134
Reputation: 120711
Strip away that bmi
and just inline the tuples (that's what the compiler will do anyway), then it becomes more obvious what's wrong:
zip' (x:xs)[] = (x,x) : zip' xs []
You have (x,x)
here, which obviously has the type of a homogenous tuple, but with the (i,b)
signature you allow for arbitrary combinations of different types.
In case you think such an intermediate function like bmi
somehow switches on type conversions, nope, there are never implicit type conversions in Haskell! (For very good reasons you'll soon appreciate with a bit more experience).
Type conversion must always be made explicit. In your case that's indeed possible, using that Integral
constraint: any two Integral
type can be converted to one another with fromIntegral
.
zip' (x:xs) [] = ( x , fromIntegral x ) : zip' xs []
zip' [] (y:ys) = ( fromIntegral y, y ) : zip' [] ys
Upvotes: 4
Reputation: 53871
The problem is that you're taking a two lists with different element types, and then when one runs out attempting to use the other lists elements in place of it. This won't work since they don't have the same type.
The simplest solution is just to fix the type signature to
zip' :: [a] -> [a] -> [(a, a)]
The other option, which I only mention because you had Integral
constraints originally, is to try to convert between each element of the list.
zip' :: (Integral i, Integral j) => [i] -> [j] -> [(i, j)]
And now you're bmi
's would look like this
...
where bmi x = (x, fromIntegral x)
...
where bmi x = (fromIntegral x, x)
...
where bmi x y = (x, y)
Upvotes: 9