Что не так с моим определением Zip в Haskell? - PullRequest
1 голос
/ 30 марта 2010
--  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 ] 

Я получаю это сообщение об ошибке:

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

Ответы [ 2 ]

10 голосов
/ 30 марта 2010

Есть три проблемы: одна - это сопоставление с шаблоном, одна - подпись типа, а другая - природа понимания списка. Вот исправленная версия:

{-# LANGUAGE ParallelListComp #-}
myzip :: [a] -> [b] -> [(a, b)]
myzip xs ys = [(x, y) | x <- xs | y <- ys]
  • Исходная подпись типа, [a] -> [a] -> [(a, a)], означала, что оба списка должны иметь элемент одного типа. Ord a был лишним и означал, что определенные типы элементов были запрещены.
  • Шаблон [x, _] <- list1 означает, что каждый элемент list1 должен быть двухэлементным списком. Вместо этого используйте x <- list1.
  • Два понимания списка представлены последовательно, а не параллельно. Думайте о запятой как, «Возьмите элементы из списка 1, затем из списка 2» (серия). Представьте, что две трубы параллельны.

Разница между сериями и параллелями:

> [[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"]
6 голосов
/ 30 марта 2010

Если вы переписываете zip, чтобы получить представление о Haskell, я бы посоветовал вам попытаться написать его, не используя списочные выражения. Понимание списков является мощным, но в некотором роде удобным сокращением для некоторых конкретных случаев в Haskell. И, как вы видите, для их использования в других случаях могут потребоваться нестандартные расширения (например, ParallelListComp).

Подумайте, что нужно сделать zip в общем случае, и что произойдет, если общий случай не будет выполнен (что может произойти двумя способами!) Уравнения для функции должны естественно выпасть из этого.

...