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

3つの問題があります。1つはパターン一致、1つは型署名、もう1つはリスト内包の性質です。修正されたバージョンは次のとおりです。

{-# LANGUAGE ParallelListComp #-}
myzip :: [a] -> [b] -> [(a, b)]
myzip xs ys = [(x, y) | x <- xs | y <- ys]
  • 元の型アノテーションは[a] -> [a] -> [(a, a)]、両方のリストが同じ型の要素を持っている必要があることを意味していました。これOrd aは不要であり、特定の種類の要素が許可されていないことを意味していました。
  • このパターン[x, _] <- list1は、の各要素がlist12要素のリストでなければならないことを意味します。x <- list1代わりに使用してください。
  • 2つのリスト内包表記は、並列ではなく直列になっています。カンマは、「list1からアイテムを取得し、次にlist2からアイテムを取得する」(シリーズ)と考えてください。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"]
于 2010-03-30T15:54:09.663 に答える
6

Haskellを理解するために書き直す場合zipは、リスト内包表記を使用せずに書き直すことをお勧めします。リスト内包表記は強力ですが、Haskellの特定のケースの便利な速記のようなものです。また、ご覧のとおり、他の場合にそれらを使用するには、非標準の拡張機能(などParallelListComp)が必要になる場合があります。

zip一般的なケースで何をする必要があるか、そして一般的なケースが満たされない場合に何が起こるかを考えてください(これは2つの方法で発生する可能性があります!)。関数の方程式は自然にそれから外れるはずです。

于 2010-03-30T16:39:06.090 に答える