Question

--  eg. myzip [’a’, ’b’, ’c’] [1, 2, 3, 4] -> [(’a’, 1), (’b’, 2), (’c’, 3)]
myzip :: Ord a => [a] -> [a] -> [(a,a)]
myzip list1 list2 = [(x,y) |  [x, _] <-list1, [y,_] <-list2 ] 

I get this error message:

 Occurs check: cannot construct the infinite type: a = [a]
    When generalising the type(s) for `myzip'
Failed, modules loaded: none.
Was it helpful?

Solution

There are three problems: One is the pattern match, one is the type signature, and one is the nature of the list comprehension. Here is a corrected version:

{-# LANGUAGE ParallelListComp #-}
myzip :: [a] -> [b] -> [(a, b)]
myzip xs ys = [(x, y) | x <- xs | y <- ys]
  • The original type signature, [a] -> [a] -> [(a, a)], meant that both lists had to have the same type of element. The Ord a was superfluous, and just meant that certain types of elements were disallowed.
  • The pattern [x, _] <- list1 means that each element of list1 must be a two-element list. Use x <- list1 instead.
  • The two list comprehensions are in series instead of parallel. Think of the comma as, "Take items from list1, then from list2" (series). Think of the two pipes as being parallel.

The difference between series and parallel:

> [[x, y] | x <- "abc", y <- "123"] -- series
["a1","a2","a3","b1","b2","b3","c1","c2","c3"]
> [[x, y] | x <- "abc" | y <- "123"] -- parallel
["a1","b2","c3"]

OTHER TIPS

If you re-writing zip in order to gain insight into Haskell, I'd suggest that you try to write it without using list comprehensions. List comprehensions are powerful, but are somewhat like a convenient shorthand for some particular cases in Haskell. And, as you see, to use them in other cases might require non-standard extensions (such as ParallelListComp).

Think about what zip needs to do in the general case, and what happens if the general case isn't met (which can happen in two ways!). The equations for the function should fall naturally out of that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top