1
--  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.
4

2 回答 2

10

存在三个问题:一个是模式匹配,一个是类型签名,一个是列表推导的性质。这是一个更正的版本:

{-# 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
  • 这两个列表推导是串行的而不是并行的。将逗号想象为“从 list1 中获取项目,然后从 list2 中获取项目”(系列)。把两条管道想象成平行的。

串联与并联的区别:

> [[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"]
于 2010-03-30T15:54:09.663 回答
6

如果您重写zip以深入了解 Haskell,我建议您尝试在不使用列表推导的情况下编写它。列表推导很强大,但有点像 Haskell 中某些特殊情况的便捷简写。而且,如您所见,在其他情况下使用它们可能需要非标准扩展(例如ParallelListComp)。

想想zip在一般情况下需要做什么,以及如果不满足一般情况会发生什么(这可能以两种方式发生!)。该函数的方程应该自然而然地排除在外。

于 2010-03-30T16:39:06.090 回答