2013-05-05 14 views
7

私はHaskellでジップ機能の次の実装を持ってHaskellの実装

myzip (a:b) (z:g) 
    | b == [] = [] 
    | g == [] = [] 
    | otherwise = (a,z) : myzip b g 

私はGHCiの中にそれをロードすると、私は、

No instance for (Eq b) 
    arising from a use of `==' 
In the expression: g == [] 
In a stmt of a pattern guard for 
       an equation for `myzip': 
    g == [] 
In an equation for `myzip': 
    myzip (a : b) (z : g) 
     | b == [] = [] 
     | g == [] = [] 
     | otherwise = (a, z) : myzip b g 

に失敗しました次のエラーを取得しますロードされたモジュール:なし。

なぜこれが機能していないのかわかりません。誰でも私に何か助けてもらえますか?

答えて

14

実際には、あなたが質問に与えた機能はうまくコンパイルされます。 myzipのリスト上の任意の作品種類abという明示的な型シグネチャを持つ

myzip :: [a] -> [b] -> [(a, b)] 
myzip (a:b) (z:g) 
    | b == [] = [] 
    | g == [] = [] 
    | otherwise = (a, z) : myzip b g 

:あなた何を持っていたことは代わりにした場合は、引用されてきたエラーを取得します。しかし、b == []g == []を使用しました。等価演算子は、Eqタイプのクラスのメンバーであるタイプでのみ、任意のタイプで定義されたではないため、記述したコードは指定したタイプと一致しません。

これはエラーメッセージがかなり簡単に言うものですが、学習していてまだクラスを入力していない場合は、少し不明です。

あなたはabEq型クラスのメンバーである必要があり、その後、あなたが与えたコードが動作することを言ってmyzipのための型シグネチャを変更する場合:

myzip :: (Eq a, Eq b) => [a] -> [b] -> [(a, b)] 

それとも、型シグネチャを残す場合GHCは実際にあなたが==演算子を使用したという事実からこのタイプを推測しています。コードはそのままの状態でコンパイルされます。

しかし、リストは==演算子を使用せずに行うことができます空であるかどうかをチェックするので、あなたはそれが本当に任意の種類ab上で動作しないようにmyzipを書くことができます。一つの方法は、null関数を使用することである。

myzip :: [a] -> [b] -> [(a, b)] 
myzip (a:b) (z:g) 
    | null b = [] 
    | null g = [] 
    | otherwise = (a, z) : myzip b g 

が、はるかに一般的な方法は、単にベースケースがパターン[]と仮定するする取得主ケースとの照合と、myzipを定義する複数の方程式を使用することですリストは空ではありません。

myzip :: [a] -> [b] -> [(a, b)] 
myzip (a:[]) _ = [] 
myzip _ (z:[]) = [] 
myzip (a:b) (z:g) = (a, z) : myzip b g 

このスタイルでは、実装にバグがあることが明らかになりました。あなたは最後のaまたはzを投げ捨てています。リストが完全に空の場合はありません。

あなたの方程式が、その後myzip (a:b) (z:g)を言った、それは実際に遅すぎる間違ったことをチェックしていた、空のリストに対してbgをチェックします。 b[]であるかどうかを確認する必要はありません。リストが空であるかどうかを確認する必要があります。しかし、あなたはすでにそれが空ではないと仮定して、それをa:bに分解しました。その結果、コード(a)は誤った結果を返すことになります。なぜなら、最後のペアの要素を破棄しなければならないし、(b)引数の1つが空のリストであるときにエラーを生成するからです。リスト上の

再帰は通常より次のようになります。これは正しく動作

myzip :: [a] -> [b] -> [(a, b)] 
myzip [] _ = [] 
myzip _ [] = [] 
myzip (a:b) (z:g) = (a, z) : myzip b g 

+5

ありがとうございました!私は投稿をして、ファーストフードを食べに出かけ、よく書かれたよく考えられた答えに戻った。インターネットは魔法のようになり、その上の人々は魔法を使う。あなたは魔法です! <3 <3 <3 – MYV

関連する問題