Pergunta

--  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 ] 

Eu recebo esta mensagem de erro:

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

Solução

Existem três problemas: um é a correspondência do padrão, uma é a assinatura do tipo e uma é a natureza da compreensão da lista. Aqui está uma versão corrigida:

{-# LANGUAGE ParallelListComp #-}
myzip :: [a] -> [b] -> [(a, b)]
myzip xs ys = [(x, y) | x <- xs | y <- ys]
  • A assinatura do tipo original, [a] -> [a] -> [(a, a)], significava que ambas as listas tinham que ter o mesmo tipo de elemento. o Ord a era supérfluo e apenas significava que certos tipos de elementos eram proibidos.
  • O padrão [x, _] <- list1 significa que cada elemento de list1 Deve ser uma lista de dois elementos. Usar x <- list1 em vez de.
  • As duas compreensões da lista são em série em vez de paralelas. Pense na vírgula como "Pegue os itens da Lista1 e depois da List2" (série). Pense nos dois tubos como paralelos.

A diferença entre séries e paralelos:

> [[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"]

Outras dicas

Se você reescrever zip Para obter informações sobre Haskell, sugiro que você tente escrevê -lo sem usar as compreensões da lista. As compreensões da lista são poderosas, mas são um pouco como uma abreviação conveniente para alguns casos particulares em Haskell. E, como você vê, usá-los em outros casos pode exigir extensões não padrão (como ParallelListComp).

Pensar sobre o que zip precisa fazer no caso geral e o que acontece se o caso geral não for atendido (o que pode acontecer de duas maneiras!). As equações para a função devem cair naturalmente disso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top