0
votes

for learning purposes I am trying to zip 2 lists together , only if the length of both matches. ( Must be the same length ) Unfortunately , it refuses to compile. I assume there is something wrong with the signature.. Thank you in anticipation. Here is my Code:

ziptogether :: (Ord a) => [a] -> [a] -> [a]
ziptogether [] [] = 0
ziptogether (x:xs) (y:ys) 
   | length(x:xs) == length(y:ys) = zip (x:xs) (y:xs)
   | otherwise = error "not same length"

Error:

     Could not deduce (a ~ (a, a))
     from the context (Ord a)
      bound by the type signature for
                ziptogether :: Ord a => [a] -> [a] -> [a]
      at new.hs:2:16-43
         `a' is a rigid type variable bound by
         the type signature for ziptogether :: Ord a => [a] -> [a] -> [a]
         at new.hs:2:16
    Expected type: [a]
     Actual type: [(a, a)]
    In the return type of a call of `zip'
    In the expression: zip (x : xs) (y : xs)
    In an equation for `ziptogether':
    ziptogether (x : xs) (y : ys)
      | length (x : xs) == length (y : ys) = zip (x : xs) (y : xs)
      | otherwise = error "not same length"
1

1 Answers

2
votes

There are a few problems. Your type signature says you take two lists and return another, your first problem is

 ziptogether [] [] = 0

So this takes to elements and returns.. a number. I think you want

 ziptogether [] [] = []

The next problem is that you recursively call zip, which returns [(a, a)]. You can change your type signature to

 ziptogether :: [a] -> [a] -> [(a, a)]
 ziptogether [] [] = []
 ziptogether (x:xs) (y:ys) | length xs == length ys = zip (x:xs) (y:ys)
                           | otherwise = error "Not the same length"

Of course you can eliminate the extra case here

 ziptogether xs ys | length xs == length ys = zip xs ys
                   | otherwise              = error "Not the same length"

Notice that we don't need an Ord constraint. You only need this if you plan to use operations like < or similar.