简体   繁体   中英

haskell Error,Zipping lists

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

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM